From 5e9cf75871d3bf04b930e206fdd4527afa619799 Mon Sep 17 00:00:00 2001 From: Daniel Brandenburg Date: Wed, 15 Jan 2025 15:55:43 -0500 Subject: [PATCH 01/10] Add enumerations for FwdVertex and accessors in StVertex --- StRoot/StEvent/StEnumerations.h | 4 +++- StRoot/StEvent/StVertex.h | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/StRoot/StEvent/StEnumerations.h b/StRoot/StEvent/StEnumerations.h index 04ff9802f83..2f35ca7162a 100644 --- a/StRoot/StEvent/StEnumerations.h +++ b/StRoot/StEvent/StEnumerations.h @@ -400,7 +400,9 @@ enum StVertexId {kUndefinedVtxId = kUndefinedVertexIdentifier, kFtpcEastCalVtxId = kFtpcEastCalibrationVertexIdentifier, kFtpcWestCalVtxId = kFtpcWestCalibrationVertexIdentifier, kBEAMConstrVtxId, - kRejectedVtxId}; + kRejectedVtxId, + kFwdVtxId + }; /*! * \enum StRichPidFlag diff --git a/StRoot/StEvent/StVertex.h b/StRoot/StEvent/StVertex.h index 4b3bb51243f..309eeeca5ca 100644 --- a/StRoot/StEvent/StVertex.h +++ b/StRoot/StEvent/StVertex.h @@ -128,6 +128,7 @@ class StVertex : public StMeasuredPoint { virtual void setKinkVertex() {SETBIT(mFlag,kKinkVtxId);} virtual void setBeamConstrained() {SETBIT(mFlag,kBEAMConstrVtxId);} virtual void setRejected() {SETBIT(mFlag,kRejectedVtxId);} + virtual void setFwdVertex() {SETBIT(mFlag,kFwdVtxId);} bool isPrimaryVtx() const {return TESTBIT(mFlag,kPrimaryVtxId);} bool isV0Vtx() const {return TESTBIT(mFlag,kV0VtxId);} @@ -135,6 +136,7 @@ class StVertex : public StMeasuredPoint { bool isKinkVertex() const {return TESTBIT(mFlag,kKinkVtxId);} bool isBeamConstrained() const {return TESTBIT(mFlag,kBEAMConstrVtxId);} bool isRejected() const {return TESTBIT(mFlag,kRejectedVtxId);} + bool isFwdVtx() const {return TESTBIT(mFlag,kFwdVtxId);} void Print(Option_t *option="") const {cout << option << *this << endl; } static void SetNoFitPointCutForGoodTrack(UInt_t val) {fgNoFitPointCutForGoodTrack = val;} static UInt_t NoFitPointCutForGoodTrack() {return fgNoFitPointCutForGoodTrack;} From 48155e60de0849dd4e3d5ba86cd2d381102b69f3 Mon Sep 17 00:00:00 2001 From: Daniel Brandenburg Date: Wed, 15 Jan 2025 21:02:48 -0500 Subject: [PATCH 02/10] Updates to StFwdTrack and StFwdTrackCollection to add accessor methods and idTruth qaTruth --- StRoot/StEvent/StFwdTrack.cxx | 5 ++++ StRoot/StEvent/StFwdTrack.h | 34 ++++++++++++++++++++----- StRoot/StEvent/StFwdTrackCollection.cxx | 7 +++++ StRoot/StEvent/StFwdTrackCollection.h | 2 +- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/StRoot/StEvent/StFwdTrack.cxx b/StRoot/StEvent/StFwdTrack.cxx index 7a95b6a2917..1e9a3ef519f 100644 --- a/StRoot/StEvent/StFwdTrack.cxx +++ b/StRoot/StEvent/StFwdTrack.cxx @@ -6,6 +6,11 @@ StFwdTrack::StFwdTrack() { } +StFwdTrack::~StFwdTrack() { + mEcalClusters.clear(); + mHcalClusters.clear(); +} + /* momentum * get the track momentum at the first point (PV if included) diff --git a/StRoot/StEvent/StFwdTrack.h b/StRoot/StEvent/StFwdTrack.h index 315f3b941e3..f74ef75ed8e 100644 --- a/StRoot/StEvent/StFwdTrack.h +++ b/StRoot/StEvent/StFwdTrack.h @@ -22,6 +22,7 @@ #include #include "StThreeVectorD.hh" #include "StContainers.h" +#include class StFcsCluster; @@ -77,18 +78,21 @@ struct StFwdTrackProjection : public StObject { struct StFwdTrackSeedPoint : public StObject { StFwdTrackSeedPoint() {} StFwdTrackSeedPoint( StThreeVectorD xyz, - short sec, + short detsec, unsigned short trackId, float cov[9] ){ mXYZ = xyz; - mSector = sec; + mSector = detsec; mTrackId = trackId; memcpy( mCov, cov, sizeof( mCov )); } + + short detectorId() const { return mSector / 10; } + short sector() const { return mSector % 10; } StThreeVectorD mXYZ; unsigned short mTrackId; - short mSector; + short mSector; // = detId * 10 + sector float mCov[9]; ClassDef(StFwdTrackSeedPoint, 1) @@ -98,6 +102,8 @@ class StFwdTrack : public StObject { public: StFwdTrack( ); + // dtor needed for releasing associations + ~StFwdTrack( ); vector mProjections; vector mFTTPoints; @@ -128,7 +134,11 @@ class StFwdTrack : public StObject { // Number of points used in the track seed step short numberOfSeedPoints() const; - + UShort_t idTruth() const { return mIdTruth; } + UShort_t qaTruth() const { return mQATruth; } + StThreeVectorD dca() const { return StThreeVectorD( mDCA[0], mDCA[1], mDCA[2] ); } + UChar_t vertexIndex() const { return mVtxIndex; } + bool isPrimary() const { return mVtxIndex != UCHAR_MAX; } void setPrimaryMomentum( StThreeVectorD mom ) { mPrimaryMomentum = mom; } void setDidFitConverge( bool lDidFitConverge ) { mDidFitConverge = lDidFitConverge; } @@ -140,6 +150,10 @@ class StFwdTrack : public StObject { void setNDF( float lNDF ) { mNDF = lNDF;} void setPval( float lPval ) { mPval = lPval;} void setCharge( short lCharge ) { mCharge = lCharge;} + void setMc( UShort_t idt, UShort_t qual ) { mIdTruth = idt; mQATruth = qual; } + void setDCA( StThreeVectorD dca ) { mDCA[0] = dca.x(); mDCA[1] = dca.y(); mDCA[2] = dca.z(); } + void setDCA( float dcaX, float dcaY, float dcaZ ) { mDCA[0] = dcaX; mDCA[1] = dcaY; mDCA[2] = dcaZ; } + void setVtxIndex( UChar_t vtxIndex ) { mVtxIndex = vtxIndex; } // ECAL clusters StPtrVecFcsCluster& ecalClusters(); @@ -168,12 +182,18 @@ class StFwdTrack : public StObject { float mPval; short mCharge; StThreeVectorD mPrimaryMomentum; - - StPtrVecFcsCluster mEcalClusters; StPtrVecFcsCluster mHcalClusters; + /// MC track id + UShort_t mIdTruth; + /// MC track quality (percentage of hits coming from corresponding MC track) + UShort_t mQATruth; + + float mDCA[3]; // DCA to the primary vertex + UChar_t mVtxIndex; - ClassDef(StFwdTrack,2) + + ClassDef(StFwdTrack,4) }; diff --git a/StRoot/StEvent/StFwdTrackCollection.cxx b/StRoot/StEvent/StFwdTrackCollection.cxx index 22e59e7790e..ca09d7130b8 100644 --- a/StRoot/StEvent/StFwdTrackCollection.cxx +++ b/StRoot/StEvent/StFwdTrackCollection.cxx @@ -15,6 +15,13 @@ ClassImp(StFwdTrackCollection) +StFwdTrackCollection::~StFwdTrackCollection(){ + for (unsigned int i=0; i Date: Tue, 28 Jan 2025 19:15:13 -0500 Subject: [PATCH 03/10] address comments from plexos & klendathu --- StRoot/StEvent/StEnumerations.h | 4 +- StRoot/StEvent/StFstConsts.h | 4 +- StRoot/StEvent/StFwdTrack.cxx | 9 +- StRoot/StEvent/StFwdTrack.h | 39 +- StRoot/StEvent/StFwdTrackCollection.cxx | 4 +- StRoot/StEvent/StFwdTrackCollection.h | 2 +- StRoot/StEvent/StVertex.h | 2 + StRoot/StFwdTrackMaker/StFwdClosureMaker.cxx | 524 +++++ StRoot/StFwdTrackMaker/StFwdClosureMaker.h | 72 + StRoot/StFwdTrackMaker/StFwdQAMaker.cxx | 464 ++++- StRoot/StFwdTrackMaker/StFwdQAMaker.h | 35 + StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx | 1710 +++++++---------- StRoot/StFwdTrackMaker/StFwdTrackMaker.h | 259 +-- .../include/Tracker/FitterUtils.h | 144 ++ .../include/Tracker/FwdDataSource.h | 26 +- .../include/Tracker/FwdGeomUtils.h | 23 +- .../StFwdTrackMaker/include/Tracker/FwdHit.h | 50 +- .../include/Tracker/FwdTracker.h | 1684 +++++++++------- .../include/Tracker/ObjExporter.h | 74 +- .../include/Tracker/TrackFitter.h | 946 +++------ StRoot/StFwdTrackMaker/macro/build_geom.C | 5 +- StRoot/StFwdTrackMaker/macro/daq/daq_track.C | 69 +- StRoot/StFwdTrackMaker/macro/daq/submit.xml | 5 - StRoot/StFwdTrackMaker/macro/event/ana.C | 42 + StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C | 137 ++ StRoot/StFwdTrackMaker/macro/mudst/mudst.C | 130 ++ StRoot/StFwdTrackMaker/macro/mudst/pico.C | 602 ++++++ .../macro/mudst/submit_pico_run22pp.xml | 43 + StRoot/StFwdTrackMaker/macro/qa/mudst.C | 78 + StRoot/StFwdTrackMaker/macro/qa/qa.C | 281 +++ StRoot/StFwdTrackMaker/macro/shell.C | 9 + StRoot/StFwdTrackMaker/macro/sim/close.C | 108 ++ StRoot/StFwdTrackMaker/macro/sim/fast.C | 145 ++ StRoot/StFwdTrackMaker/macro/sim/gen | 17 + StRoot/StFwdTrackMaker/macro/sim/gen.C | 87 +- .../macro/sim/ideal-sim-fst-seed | 2 + .../macro/sim/ideal-sim-ftt-seed | 2 + StRoot/StFwdTrackMaker/macro/sim/jpsi | 16 + StRoot/StFwdTrackMaker/macro/sim/jpsi.C | 225 +++ StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C | 181 ++ StRoot/StFwdTrackMaker/macro/sim/lambda.C | 191 ++ .../macro/sim/real-sim-fst-seed | 2 + .../macro/sim/real-sim-ftt-seed | 2 + StRoot/StFwdTrackMaker/macro/sim/sim.C | 242 +++ .../macro/sim/single_particle_gun.C | 28 + StRoot/StFwdTrackMaker/macro/viz.C | 210 +- StRoot/StFwdTrackMaker/macro/viz2.C | 600 ++++++ StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx | 24 +- StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx | 26 +- StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h | 77 +- StRoot/StPicoDstMaker/StPicoDstMaker.cxx | 112 ++ StRoot/StPicoDstMaker/StPicoDstMaker.h | 6 + StRoot/StPicoEvent/StPicoArrays.cxx | 21 +- StRoot/StPicoEvent/StPicoArrays.h | 7 +- StRoot/StPicoEvent/StPicoDst.cxx | 17 + StRoot/StPicoEvent/StPicoDst.h | 17 + StRoot/StPicoEvent/StPicoDstLinkDef.h | 3 + StRoot/StPicoEvent/StPicoDstReader.cxx | 6 + StRoot/StPicoEvent/StPicoFcsCluster.cxx | 39 + StRoot/StPicoEvent/StPicoFcsCluster.h | 80 + StRoot/StPicoEvent/StPicoFcsHit.cxx | 27 + StRoot/StPicoEvent/StPicoFcsHit.h | 53 + StRoot/StPicoEvent/StPicoFwdTrack.cxx | 55 + StRoot/StPicoEvent/StPicoFwdTrack.h | 110 ++ 64 files changed, 7376 insertions(+), 2838 deletions(-) create mode 100644 StRoot/StFwdTrackMaker/StFwdClosureMaker.cxx create mode 100644 StRoot/StFwdTrackMaker/StFwdClosureMaker.h create mode 100644 StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h create mode 100755 StRoot/StFwdTrackMaker/macro/event/ana.C create mode 100644 StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C create mode 100755 StRoot/StFwdTrackMaker/macro/mudst/mudst.C create mode 100755 StRoot/StFwdTrackMaker/macro/mudst/pico.C create mode 100644 StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml create mode 100755 StRoot/StFwdTrackMaker/macro/qa/mudst.C create mode 100755 StRoot/StFwdTrackMaker/macro/qa/qa.C create mode 100755 StRoot/StFwdTrackMaker/macro/shell.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/close.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/fast.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/gen mode change 100644 => 100755 StRoot/StFwdTrackMaker/macro/sim/gen.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/ideal-sim-fst-seed create mode 100755 StRoot/StFwdTrackMaker/macro/sim/ideal-sim-ftt-seed create mode 100755 StRoot/StFwdTrackMaker/macro/sim/jpsi create mode 100755 StRoot/StFwdTrackMaker/macro/sim/jpsi.C create mode 100644 StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/lambda.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/real-sim-fst-seed create mode 100755 StRoot/StFwdTrackMaker/macro/sim/real-sim-ftt-seed create mode 100755 StRoot/StFwdTrackMaker/macro/sim/sim.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C mode change 100644 => 100755 StRoot/StFwdTrackMaker/macro/viz.C create mode 100755 StRoot/StFwdTrackMaker/macro/viz2.C create mode 100644 StRoot/StPicoEvent/StPicoFcsCluster.cxx create mode 100644 StRoot/StPicoEvent/StPicoFcsCluster.h create mode 100644 StRoot/StPicoEvent/StPicoFcsHit.cxx create mode 100644 StRoot/StPicoEvent/StPicoFcsHit.h create mode 100644 StRoot/StPicoEvent/StPicoFwdTrack.cxx create mode 100644 StRoot/StPicoEvent/StPicoFwdTrack.h diff --git a/StRoot/StEvent/StEnumerations.h b/StRoot/StEvent/StEnumerations.h index 04ff9802f83..2f35ca7162a 100644 --- a/StRoot/StEvent/StEnumerations.h +++ b/StRoot/StEvent/StEnumerations.h @@ -400,7 +400,9 @@ enum StVertexId {kUndefinedVtxId = kUndefinedVertexIdentifier, kFtpcEastCalVtxId = kFtpcEastCalibrationVertexIdentifier, kFtpcWestCalVtxId = kFtpcWestCalibrationVertexIdentifier, kBEAMConstrVtxId, - kRejectedVtxId}; + kRejectedVtxId, + kFwdVtxId + }; /*! * \enum StRichPidFlag diff --git a/StRoot/StEvent/StFstConsts.h b/StRoot/StEvent/StFstConsts.h index fd84cc5ed12..f91d8214c39 100644 --- a/StRoot/StEvent/StFstConsts.h +++ b/StRoot/StEvent/StFstConsts.h @@ -52,8 +52,8 @@ const float kFstrStart[kFstNumRStripsPerWedge]= {5.000, 7.875, 10.750, 13.625, 1 const float kFstrStop[kFstNumRStripsPerWedge] = {7.875, 10.750, 136.25, 16.500, 19.375, 22.250, 25.125, 28.000}; // in cm //general APV chip constants -const unsigned char kFstNumTimeBins = 9; // 9 time bins for ADC sampling (maximum time bin number, 3 or 9) -const unsigned char kFstDefaultTimeBin = 2; // the default time bin number (2nd time bin) for FST raw hits +const unsigned char kFstNumTimeBins = 3; // 9 time bins for ADC sampling (maximum time bin number, 3 or 9) +const unsigned char kFstDefaultTimeBin = 1; // the default time bin number (2nd time bin) for FST raw hits const int kFstMaxAdc = 4096; // ADC value should be less than 4096 (12 bits ADC) #endif diff --git a/StRoot/StEvent/StFwdTrack.cxx b/StRoot/StEvent/StFwdTrack.cxx index 1e9a3ef519f..2cbb5dca531 100644 --- a/StRoot/StEvent/StFwdTrack.cxx +++ b/StRoot/StEvent/StFwdTrack.cxx @@ -2,14 +2,9 @@ #include "StEvent/StFcsCluster.h" #include "St_base/StMessMgr.h" -StFwdTrack::StFwdTrack() { +StFwdTrack::StFwdTrack() {} -} - -StFwdTrack::~StFwdTrack() { - mEcalClusters.clear(); - mHcalClusters.clear(); -} +StFwdTrack::~StFwdTrack() {} /* momentum diff --git a/StRoot/StEvent/StFwdTrack.h b/StRoot/StEvent/StFwdTrack.h index f74ef75ed8e..7b4724b2022 100644 --- a/StRoot/StEvent/StFwdTrack.h +++ b/StRoot/StEvent/StFwdTrack.h @@ -169,32 +169,27 @@ class StFwdTrack : public StObject { protected: - - // Track quality and convergence - bool mDidFitConverge; - bool mDidFitConvergeFully; - short mNumberOfFailedPoints; - short mNumberOfSeedPoints; - short mNumberOfFitPoints; - float mChi2; - float mNDF; - float mPval; - short mCharge; - StThreeVectorD mPrimaryMomentum; - StPtrVecFcsCluster mEcalClusters; - StPtrVecFcsCluster mHcalClusters; - /// MC track id - UShort_t mIdTruth; - /// MC track quality (percentage of hits coming from corresponding MC track) - UShort_t mQATruth; - - float mDCA[3]; // DCA to the primary vertex - UChar_t mVtxIndex; + bool mDidFitConverge; // did the fit converge + bool mDidFitConvergeFully; // did the fit converge fully (forward and backward) + short mNumberOfFailedPoints; // number of failed points + short mNumberOfSeedPoints; // number of seed points + short mNumberOfFitPoints; // number of fit points (seeds + vertex) + float mChi2; // chi2 of the fit + float mNDF; // number of degrees of freedom + float mPval; // p-value of the fit + short mCharge; // charge of the track + StThreeVectorD mPrimaryMomentum; // momentum at the primary vertex + StPtrVecFcsCluster mEcalClusters; // ECAL clusters + StPtrVecFcsCluster mHcalClusters; // HCAL clusters + UShort_t mIdTruth; // MC track id + UShort_t mQATruth; // MC track quality (percentage of hits coming from corresponding MC track) - ClassDef(StFwdTrack,4) + float mDCA[3]; // DCA to the primary vertex + UChar_t mVtxIndex; // index of the primary vertex + ClassDef(StFwdTrack,3) }; #endif diff --git a/StRoot/StEvent/StFwdTrackCollection.cxx b/StRoot/StEvent/StFwdTrackCollection.cxx index ca09d7130b8..ff0577b79e6 100644 --- a/StRoot/StEvent/StFwdTrackCollection.cxx +++ b/StRoot/StEvent/StFwdTrackCollection.cxx @@ -17,8 +17,8 @@ ClassImp(StFwdTrackCollection) StFwdTrackCollection::~StFwdTrackCollection(){ for (unsigned int i=0; i mFitter = nullptr; +std::unique_ptr mBField; +std::map< string, TH1* > mHistograms; + +TH1 * addHistogram1D( string name, string title, int nbins, double min, double max ){ + TH1 * h = new TH1F( name.c_str(), title.c_str(), nbins, min, max ); + mHistograms[name] = h; + return h; +} + +TH2 * addHistogram2D( string name, string title, int nbinsX, double minX, double maxX, int nbinsY, double minY, double maxY ){ + TH2 * h = new TH2F( name.c_str(), title.c_str(), nbinsX, minX, maxX, nbinsY, minY, maxY ); + mHistograms[name] = h; + return h; +} + +TH1 * getHistogram1D( string name ){ + if ( mHistograms.count(name) ) + return mHistograms[name]; + assert( false && "Histogram not found" ); + return nullptr; +} +TH2 * getHistogram2D( string name ){ + return dynamic_cast( getHistogram1D(name) ); +} + +struct Point { + double x, y; +}; + +// Function to calculate the determinant of a 2x2 matrix +double determinant(double a, double b, double c, double d) { + return a * d - b * c; +} + +// Function to compute the curvature of a circle given 3 points +double computeCurvature(const Point& p1, const Point& p2, const Point& p3) { + // Calculate the lengths of the sides of the triangle + double A = std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2)); + double B = std::sqrt(std::pow(p3.x - p2.x, 2) + std::pow(p3.y - p2.y, 2)); + double C = std::sqrt(std::pow(p1.x - p3.x, 2) + std::pow(p1.y - p3.y, 2)); + + // Calculate the determinant of the matrix formed by the points + double det = determinant(p2.x - p1.x, p2.y - p1.y, p3.x - p1.x, p3.y - p1.y); + // LOG_INFO << "Det: " << det << endm; + double charge = det > 0 ? -1 : 1; + // Area of the triangle formed by the three points + double area = std::abs(det) / 2.0; + + if (area == 0) { + std::cerr << "The points are collinear, curvature is undefined." << std::endl; + return -1; // Curvature is undefined for collinear points + } + + // Calculate the radius of the circumcircle using the formula: + // R = (A * B * C) / (4 * area) + double radius = (A * B * C) / (4 * area); + // LOG_INFO << "Radius: " << radius << endm; + // Curvature is the inverse of the radius + return charge / radius; +} + +int StFwdClosureMaker::Init() { + + /****************************************************** + * Setup GenFit + */ + // Setup the Geometry used by GENFIT + TGeoManager::Import("fGeom.root"); + gMan = gGeoManager; + // Set up the material interface and set material effects on/off from the config + genfit::MaterialEffects::getInstance()->init(new genfit::TGeoMaterialInterface()); + genfit::MaterialEffects::getInstance()->setNoEffects( true ); + // Setup the BField to use + // mBField = std::unique_ptr(new genfit::ConstField(0., 0., 5)); // 0.5 T Bz + mBField = std::unique_ptr(new StarFieldAdaptor()); + genfit::FieldManager::getInstance()->init(mBField.get()); + + // initialize the main mFitter using a KalmanFitter with reference tracks + mFitter = std::unique_ptr(new genfit::KalmanFitterRefTrack( + /*maxIterations = */ mMaxIt, + /*deltaPval = */ mPVal, + /*blowUpFactor = */ mBlowUp + )); + + mFitter->setRelChi2Change( mRelChi2 ); + + // Setup the histograms + addHistogram2D( "PtCorrelation", "PtCorrelation; MC; RC;", 100, 0, 1, 100, 0, 1 ); + addHistogram1D( "PtResolution", "PtResolution; (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, -5, 5 ); + addHistogram1D( "CurveResolution", "CurveResolution; (1/p_{T}^{MC} - 1/p_{T}^{RC}) / 1/p_{T}^{MC};", 100, -5, 5 ); + 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 ); + addHistogram2D( "PtResolutionVsPt", "PtResolution; Pt (GeV/c); (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, 0, 2.0, 100, -5, 5 ); + addHistogram1D( "PointCurvePtResolution", "PointCurve PtResolution; (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, -5, 5 ); + addHistogram1D( "PointCurveCurveResolution", "PointCurve CurveResolution; (1/p_{T}^{MC} - 1/p_{T}^{RC}) / 1/p_{T}^{MC};", 100, -5, 5 ); + + addHistogram1D( "QCurve", "QCurve; q/Pt;", 100, -5, 5 ); + addHistogram2D( "QMatrix", "QMatrix; MC; RC;", 4, -2, 2, 4, -2, 2 ); + addHistogram2D( "QidVsPt", "QMatrix; Pt; Qid;", 100, 0, 2.0, 2, -0.5, 1.5 ); + return kStOk; +} + + + +int StFwdClosureMaker::Finish() { + + getHistogram1D("PtResolution")->Draw(); + gPad->Print( "ClosurePtResolution.pdf" ); + + getHistogram1D("CurveResolution")->Draw(); + gPad->Print( "ClosureCurveResolution.pdf" ); + + getHistogram1D("PointCurvePtResolution")->Draw(); + gPad->Print( "ClosurePointCurvePtResolution.pdf" ); + + getHistogram1D("PointCurveCurveResolution")->Draw(); + gPad->Print( "ClosurePointCurveCurveResolution.pdf" ); + + TFile * fOut = new TFile(mOutFile, "RECREATE"); + fOut->cd(); + for ( auto h : mHistograms ){ + h.second->Write(); + } + + return kStOk; +} + + +int StFwdClosureMaker::Make() { + LOG_INFO << "Make (StFwdClosureMaker)" << endm; + + /***************************************************** + * Load the MC Vertex + */ + St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); + if (!g2t_vertex) + return 0; + + /***************************************************** + * Load the MC Tracks + */ + // Store the McMomentum for the first track (assuming single particle gun) + TVector3 mcMom(0,0,0); + int mcQ = 0; + // Get geant tracks + St_g2t_track *g2t_track = (St_g2t_track *)GetDataSet("geant/g2t_track"); + if (!g2t_track) + return 0; + + LOG_DEBUG << g2t_track->GetNRows() << " mc tracks in geant/g2t_track " << endm; + // Load the MC track info + for (int irow = 0; irow < g2t_track->GetNRows(); irow++) { + g2t_track_st *track = (g2t_track_st *)g2t_track->At(irow); + + if (0 == track) + continue; + + int track_id = track->id; + float pt2 = track->p[0] * track->p[0] + track->p[1] * track->p[1]; + float pt = std::sqrt(pt2); + float eta = track->eta; + TVector3 pp( track->p[0], track->p[1], track->p[2] ); + if ( track_id == 1 ){ + mcMom.SetXYZ( track->p[0], track->p[1], track->p[2] ); + mcQ = track->charge; + } + float phi = std::atan2(track->p[1], track->p[0]); //track->phi; + int q = track->charge; + LOG_INFO << "McTrack: " << track_id << ", pt = " << pt << ", eta = " << eta << ", phi = " << phi << ", q = " << q << endm; + } + + + + vector spoints; + + /***************************************************** + * Load the FST hits + */ + St_g2t_fts_hit *g2t_fsi_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_fsi_hit"); + if ( !g2t_fsi_hits ){ + LOG_DEBUG << "No g2t_fts_hits, cannot load FST hits from GEANT" << endm; + return 0; + } + + // reuse this to store cov mat + TMatrixDSym hitCov3(3); + const double sigXY = 0.01; + hitCov3(0, 0) = sigXY * sigXY; + hitCov3(1, 1) = sigXY * sigXY; + hitCov3(2, 2) = 0.1; + + TMatrixDSym vStripCov3(3); + vStripCov3(0, 0) = sigXY * sigXY; + vStripCov3(1, 1) = 50; + vStripCov3(2, 2) = 0.1; + + TMatrixDSym hStripCov3(3); + hStripCov3(0, 0) = 50; + hStripCov3(1, 1) = sigXY * sigXY; + hStripCov3(2, 2) = 0.1; + + /***************************************************** + * Add Primary Vertex to the track + */ + if ( g2t_vertex != nullptr ) { + // Set the MC Vertex for track fitting + g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0); + TMatrixDSym cov; + cov.ResizeTo(3, 3); + cov(0, 0) = pow(mPrimaryVertexSigXY,2); + cov(1, 1) = pow(mPrimaryVertexSigXY,2); + cov(2, 2) = pow(mPrimaryVertexSigZ, 2); + auto rhc = TVectorD( 3 ); + rhc[0] = vert->ge_x[0]; + rhc[1] = vert->ge_x[1]; + rhc[2] = vert->ge_x[2]; + auto spoint = new genfit::SpacepointMeasurement(rhc, cov, 0, 0, nullptr); + spoints.push_back(spoint); + // mForwardTracker->setEventVertex( TVector3( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ), cov ); + } + + /***************************************************** + * Add FST hits to the track + */ + for (int i = 0; i < g2t_fsi_hits->GetNRows(); i++) { + + g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_fsi_hits->At(i); + if (0 == git) + continue; // geant hit + + // int track_id = git->track_p; + int volume_id = git->volume_id; // 4, 5, 6 + int d = volume_id / 1000; // disk id + + // int plane_id = d - 4; + float x = git->x[0]; + float y = git->x[1]; + float z = git->x[2]; + + auto rhc = TVectorD( 3 ); + TVector3 rastered = raster( TVector3( x, y, z ) ); + rhc[0] = rastered.X(); + rhc[1] = rastered.Y(); + rhc[2] = rastered.Z(); + auto spoint = new genfit::SpacepointMeasurement(rhc, makeSiCovMat(TVector3( x, y, z )), 0, i+1, nullptr); + spoints.push_back(spoint); + LOG_INFO << "FST HIT: d = " << d << ", x=" << x << ", y=" << y << ", z=" << z << endm; + } + + St_g2t_fts_hit *g2t_stg_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_stg_hit"); + if (!g2t_stg_hits){ + LOG_WARN << "geant/g2t_stg_hit is empty" << endm; + return kStOk; + } + int nstg = g2t_stg_hits->GetNRows(); + + LOG_DEBUG << "This event has " << nstg << " stg hits in geant/g2t_stg_hit " << endm; + int nFttHits = 0; + for (int i = 0; i < nstg; i++) { + + g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_stg_hits->At(i); + if (0 == git) + continue; // geant hit + // int track_id = git->track_p; + int volume_id = git->volume_id; + int plane_id = (volume_id - 1) / 100; // from 1 - 16. four chambers per station + + // only use the hits on the front modules + if ( mFttMode == kPoint && volume_id % 2 ==0 ) + continue; + + float x = git->x[0]; + float y = git->x[1]; + float z = git->x[2]; + + if (plane_id < 0 || plane_id >= 4) { + continue; + } + + auto rhc = TVectorD( 3 ); + rhc[0] = x; + rhc[1] = y; + rhc[2] = z; + LOG_INFO << "FTT HIT: plane_id = " << plane_id << ", volume_d = " << volume_id << " x=" << x << ", y=" << y << ", z=" << z << endm; + + if ( kPoint == mFttMode ){ + auto spoint = new genfit::SpacepointMeasurement(rhc, hitCov3, 0, i+4, nullptr); + if ( nFttHits < mNumFttToUse ) + spoints.push_back(spoint); + } else { + if ( volume_id % 2 == 0 ){ + auto spoint = new genfit::SpacepointMeasurement(rhc, vStripCov3, 0, i+4, nullptr); + if ( nFttHits < mNumFttToUse ) + spoints.push_back(spoint); + } else { + auto spoint = new genfit::SpacepointMeasurement(rhc, hStripCov3, 0, i+4, nullptr); + if ( nFttHits < mNumFttToUse ) + spoints.push_back(spoint); + } + } + + nFttHits++; + } + + float ptCurve = 9999.0; + float qCurve = 1.0; + if ( spoints.size() >= 3 ){ + double curve = computeCurvature( {spoints[0]->getRawHitCoords()[0], spoints[0]->getRawHitCoords()[1]}, + {spoints[1]->getRawHitCoords()[0], spoints[1]->getRawHitCoords()[1]}, + {spoints[2]->getRawHitCoords()[0], spoints[2]->getRawHitCoords()[1]} ); + const double K = 0.00029979; //K depends on the units used for Bfield + const double BStrength = 5; // 0.5 T + double pt = fabs((K*BStrength)/curve); // pT from average measured curv + qCurve = curve > 0 ? 1 : -1; + ptCurve = pt; + LOG_INFO << "Curve: " << curve << ", Pt: " << pt << endm; + } + + + /***************************************************** + * Setup the Genfit Fit Track + */ + auto theTrackRep = new genfit::RKTrackRep(-13 * qCurve); + auto seedPos = TVector3(0, 0, 0); + auto seedMom = TVector3(0, 0, 10); + // seedMom.SetPtEtaPhi( ptCurve, 3.0, 0 ); + auto mFitTrack = std::make_shared(theTrackRep, seedPos, seedMom); + + LOG_INFO << "Track fit with " << spoints.size() << " space points" << endm; + try { + for ( size_t i = 0; i < spoints.size(); i++ ){ + mFitTrack->insertPoint(new genfit::TrackPoint(spoints[i], mFitTrack.get())); + } + + LOG_INFO << "Track prep = " << mFitter->isTrackPrepared( mFitTrack.get(), theTrackRep ) << endm; + + // mFitter->checkConsistency(); + mFitTrack->checkConsistency(); + // mFitter->processTrack(mFitTrack.get()); + mFitter->processTrack(mFitTrack.get()); + + mFitTrack->checkConsistency(); + mFitTrack->determineCardinalRep(); + + // mFitter->processTrack(mFitTrack.get()); + + + auto status = mFitTrack->getFitStatus(); + LOG_INFO << "Fit status: " << status->isFitConverged() << endm; + LOG_INFO << "-Fit pvalue: " << status->getPVal() << endm; + LOG_INFO << "-Fit Chi2: " << status->getChi2() << endm; + + + + auto cr = mFitTrack->getCardinalRep(); + auto p = cr->getMom( mFitTrack->getFittedState( 0, cr )); + int rcQ = status->getCharge(); + LOG_INFO << "Fit momentum: " << p.X() << ", " << p.Y() << ", " << p.Z() << endm; + LOG_INFO << "\tFit Pt: " << p.Pt() << ", eta: " << p.Eta() << ", phi: " << p.Phi() << endm; + LOG_INFO << "\tMc Pt: " << mcMom.Pt() << ", eta: " << mcMom.Eta() << ", phi: " << mcMom.Phi() << endm; + + + if (status->isFitConvergedPartially()){ + getHistogram1D("PtResolution")->Fill( (p.Pt() - mcMom.Pt()) / mcMom.Pt() ); + getHistogram1D("CurveResolution")->Fill( (1/p.Pt() - 1/mcMom.Pt()) / (1/mcMom.Pt()) ); + getHistogram1D("PtCorrelation")->Fill( mcMom.Pt(), p.Pt() ); + getHistogram1D("QCurve")->Fill( rcQ / p.Pt() ); + + getHistogram1D("PointCurvePtResolution")->Fill( (ptCurve - mcMom.Pt()) / mcMom.Pt() ); + getHistogram1D("PointCurveCurveResolution")->Fill( (1/ptCurve - 1/mcMom.Pt()) / (1/mcMom.Pt()) ); + + getHistogram2D("PtResolutionVsPt")->Fill( mcMom.Pt(), (p.Pt() - mcMom.Pt()) / mcMom.Pt() ); + getHistogram2D("CurveResolutionVsPt")->Fill( mcMom.Pt(), (1/p.Pt() - 1/mcMom.Pt()) / (1/mcMom.Pt()) ); + + getHistogram2D("QMatrix")->Fill( mcQ, rcQ ); + getHistogram2D("QidVsPt")->Fill( mcMom.Pt(), mcQ == rcQ ? 1 : 0 ); + } + else { + LOG_INFO << "Fit did not converge" << endm; + } + + + } catch (genfit::Exception &e) { + LOG_ERROR << "GenFit failed to fit track with: " << e.what() << endm; + } + + // load the space points from fst geant hits + + + // for (size_t i = 0; i < trackSeed.size(); i++) { + // auto seed = trackSeed[i]; + // TMatrixDSym cm(3); + // cm(0, 0) = 0.01; + // cm(1, 1) = 0.01; + // cm(2, 2) = 0.01; + // auto rhc = TVectorD( 3 ); + // rhc[0] = seed->getX(); + // rhc[1] = seed->getY(); + // rhc[2] = seed->getZ(); + // auto spoint = new genfit::SpacepointMeasurement(rhc, cm, 0, i, nullptr); + // spoints.push_back(spoint); + // } + + return kStOk; +} +void StFwdClosureMaker::Clear(const Option_t *opts) { + return; +} \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/StFwdClosureMaker.h b/StRoot/StFwdTrackMaker/StFwdClosureMaker.h new file mode 100644 index 00000000000..a8a9b0a452a --- /dev/null +++ b/StRoot/StFwdTrackMaker/StFwdClosureMaker.h @@ -0,0 +1,72 @@ +#ifndef ST_FWD_CLOSURE_MAKER_H +#define ST_FWD_CLOSURE_MAKER_H + +#include "TClonesArray.h" +#ifndef __CINT__ +#include "GenFit/Track.h" +#include "StFwdTrackMaker/include/Tracker/FwdHit.h" +#include "StMuDSTMaker/COMMON/StMuFwdTrack.h" +#endif + +#include "StChain/StMaker.h" +#include "TTree.h" +#include "TVector3.h" +#include "TLorentzVector.h" +#include "StEvent/StEnumerations.h" +#include "StThreeVectorD.hh" +#include "StThreeVectorF.hh" +#include "StPhysicalHelixD.hh" + +#include + + +class StMuDstMaker; +class StMuDst; +class StMuFwdTrackCollection; +class StMuFcsCollection; +class StFwdTrackMaker; +class StEvent; + +class StFwdClosureMaker : public StMaker { + + ClassDef(StFwdClosureMaker, 0); + + public: + StFwdClosureMaker(); + ~StFwdClosureMaker(){/* nada */}; + + int Init(); + int Finish(); + int Make(); + void Clear(const Option_t *opts = ""); + +#ifndef __CINT__ + TVector3 raster(TVector3 p0); + TMatrixDSym makeSiCovMat(TVector3 hit); +#endif + + // protected: + + float mPVal = 1e-3; + float mBlowUp = 1e3; + int mMaxIt = 40; + float mRelChi2 = 0.1; + + // Primary Vertex resolutions + double mPrimaryVertexSigXY = 10.1; // in cm (e.g. 0.01 = 100 microns) + double mPrimaryVertexSigZ = 10.1; // in cm (e.g. 0.01 = 100 microns) + + // FST resolutions + double mRasterR = 3.0; + double mRasterPhi = 0.004; + + // use FTT in tracking? + int mNumFttToUse = 4; + enum FttMode { kStrip, kPoint}; + FttMode mFttMode = kPoint; + + TString mOutFile = "fwdClosure.root"; +}; + + +#endif diff --git a/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx b/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx index b7ce1cd225e..f356722b090 100644 --- a/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx +++ b/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx @@ -36,8 +36,6 @@ #include "StMuDSTMaker/COMMON/StMuMcTrack.h" #include "StMuDSTMaker/COMMON/StMuFstHit.h" -// ClassImp(FcsClusterWithStarXYZ); - /** Clear the FwdQATreeData from one event to next */ void FwdQATreeData::clear(){ header.clear(); @@ -93,12 +91,12 @@ FcsHitWithStarXYZ::FcsHitWithStarXYZ( StMuFcsHit *hit, StFcsDb *fcsDb ) { } StFwdQAMaker::StFwdQAMaker() : StMaker("fwdQAMaker"), mTreeFile(nullptr), mTree(nullptr) { - + setLocalOutputFile( "./fwdHists.root" ); // default off } int StFwdQAMaker::Init() { - mTreeFile = new TFile("fwdtree.root", "RECREATE"); + mTreeFile = new TFile( mTreeFilename.Data(), "RECREATE"); mTree = new TTree("fwd", "fwd tracking tree"); mTree->Branch("header", &mTreeData. header, 3200, 99 ); @@ -107,7 +105,6 @@ int StFwdQAMaker::Init() { mTreeData.fstPoints.createBranch(mTree, "fstHits"); mTreeData.fttPoints.createBranch(mTree, "fttPoints"); mTreeData.fttClusters.createBranch(mTree, "fttClusters"); - mTreeData.fstPoints.createBranch(mTree, "fstPoints"); mTreeData.wcal.createBranch(mTree, "wcalClusters"); mTreeData.hcal.createBranch(mTree, "hcalClusters"); @@ -117,8 +114,63 @@ int StFwdQAMaker::Init() { mTreeData.reco.createBranch(mTree, "reco"); mTreeData.seeds.createBranch(mTree, "seeds"); + + + + //========================================================================================================= adding histograms (new) + AddHist( mHists["fwdMultFailed"] = new TH1F("fwdMultFailed", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultAll"] = new TH1F("fwdMultAll", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultGood"] = new TH1F("fwdMultGood", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultFST"] = new TH1F("fwdMultFST", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["nHitsFit"] = new TH1F("nHitsFit", ";nHitsFit; counts", 10, 0, 10) ); + AddHist( mHists["fwdMultEcalMatch"] = new TH1F("fwdMultEcalMatch", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultHcalMatch"] = new TH1F("fwdMultHcalMatch", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultEcalClusters"] = new TH1F("fwdMultEcalClusters", ";N_{Clu}^{ECAL}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultHcalClusters"] = new TH1F("fwdMultHcalClusters", ";N_{Clu}^{HCAL}; counts", 100, 0, 100) ); + AddHist( mHists["eta"] = new TH1F("eta", ";#eta; counts", 100, 0, 5) ); + AddHist( mHists["phi"] = new TH1F("phi", ";#phi; counts", 100, -3.1415926, 3.1415926) ); + AddHist( mHists["pt"] = new TH1F("pt", "; pT; counts", 500, 0, 10) ); + AddHist( mHists["charge"] = new TH1F("charge", "; charge; counts", 4, -2, 2) ); + AddHist( mHists["ecalMatchPerTrack"] = new TH1F("ecalMatchPerTrack", ";N_{match} / track; counts", 5, 0, 5) ); + AddHist( mHists["hcalMatchPerTrack"] = new TH1F("hcalMatchPerTrack", ";N_{match} / track; counts", 5, 0, 5) ); + AddHist( mHists["matchedEcalEnergy"] = new TH1F("matchedEcalEnergy", ";Energy; counts", 100, 0, 15) ); + AddHist( mHists["matchedHcalEnergy"] = new TH1F("matchedHcalEnergy", ";Energy; counts", 100, 0, 15) ); + AddHist( mHists["ecalEnergy"] = new TH1F("ecalEnergy", ";Energy; counts", 100, 0, 15) ); + AddHist( mHists["hcalEnergy"] = new TH1F("hcalEnergy", ";Energy; counts", 100, 0, 15) ); + AddHist( mHists["ecalXY"] = new TH2F( "ecalXY", ";ecalX;ecalY", 200, -200, 200, 200, -200, 200 ) ); + AddHist( mHists["hcalXY"] = new TH2F( "hcalXY", ";hcalX;hcalY", 200, 0, 50, 200, 0, 50 ) ); + AddHist( mHists["ecaldX"] = new TH1F( "ecaldX", ";dx (trk - ecal); counts", 400, -200, 200 ) ); + AddHist( mHists["matchedEcaldX"] = new TH1F( "matchedEcaldX", ";dx (trk - ecal); counts", 400, -200, 200 ) ); + AddHist( mHists["ecaldY"] = new TH1F( "ecaldY", ";dy (trk - ecal); counts", 400, -200, 200 ) ); + AddHist( mHists["matchedEcaldY"] = new TH1F( "matchedEcaldY", ";dy (trk - ecal); counts", 400, -200, 200 ) ); + AddHist( mHists["ecaldR"] = new TH1F( "ecaldR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); + AddHist( mHists["ecalMindR"] = new TH1F( "ecalMindR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); + AddHist( mHists["matchedEcaldR"] = new TH1F( "matchedEcaldR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); + AddHist( mHists["hcaldX"] = new TH1F( "hcaldX", ";dx (trk - hcal); counts", 400, -200, 200 ) ); + AddHist( mHists["hcaldXdNFit"] = new TH2F( "hcaldXdNFit", ";dx (trk - hcal); nFit", 400, -200, 200, 10, 0, 10 ) ); + AddHist( mHists["matchedHcaldX"] = new TH1F( "matchedHcaldX", ";dx (trk - hcal); counts", 400, -200, 200 ) ); + AddHist( mHists["hcaldY"] = new TH1F( "hcaldY", ";dy (trk - hcal); counts", 400, -200, 200 ) ); + AddHist( mHists["hcaldYdNFit"] = new TH2F( "hcaldYdNFit", ";dy (trk - hcal); nFit", 400, -200, 200, 10, 0, 10 ) ); + AddHist( mHists["matchedHcaldY"] = new TH1F( "matchedHcaldY", ";dy (trk - hcal); counts", 400, -200, 200 ) ); + AddHist( mHists["hcaldR"] = new TH1F( "hcaldR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); + AddHist( mHists["hcalMindR"] = new TH1F( "hcalMindR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); + AddHist( mHists["matchedHcaldR"] = new TH1F( "matchedHcaldR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); + AddHist( mHists["trkEcalX"] = new TH2F( "trkEcalX", ";trkX;ecalX", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkEcalY"] = new TH2F( "trkEcalY", ";trkY;ecalY", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkEcalMinX"] = new TH2F( "trkEcalMinX", ";trkX;ecalX", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkEcalMinY"] = new TH2F( "trkEcalMinY", ";trkY;ecalY", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkHcalX"] = new TH2F( "trkHcalX", ";trkX;hcalX", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkHcalY"] = new TH2F( "trkHcalY", ";trkY;hcalY", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkHcalMinX"] = new TH2F( "trkHcalMinX", ";trkX;hcalX", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkHcalMinY"] = new TH2F( "trkHcalMinY", ";trkY;hcalY", 300, -150, 150, 300, -150, 150 ) ); + +//=================================================================================================================================== + return kStOk; } + + + int StFwdQAMaker::Finish() { if ( mTreeFile && mTree ){ @@ -127,8 +179,29 @@ int StFwdQAMaker::Finish() { mTreeFile->Write(); LOG_DEBUG << "StFwdQA File written" << endm; } + + //beginning new + if ( mLocalOutputFile != "" ){ + auto prevDir = gDirectory; + + // output file name + TFile *fOutput = new TFile(mLocalOutputFile, "RECREATE"); + fOutput->cd(); + for (auto nh : mHists) { + nh.second->SetDirectory(gDirectory); + nh.second->Write(); + } + + // restore previous directory + gDirectory = prevDir; + + LOG_INFO << "Done writing StFwdQAMaker output to local file : " << mLocalOutputFile << endm; + }//end new + return kStOk; } + + int StFwdQAMaker::Make() { LOG_INFO << "FWD Report:" << endm; StEvent *mStEvent = static_cast(GetInputDS("StEvent")); @@ -136,46 +209,50 @@ int StFwdQAMaker::Make() { // report number of fwd tracks auto fwdTracks = mStEvent->fwdTrackCollection(); LOG_INFO << "Number of FwdTracks (StFwdTrackCollection): " << fwdTracks->tracks().size() << endm; - LOG_INFO << "Number of Ftt Points (StEvent)" << mStEvent->fttCollection()->points().size() << endm; + if ( mStEvent->fttCollection() ){ + LOG_INFO << "Number of Ftt Points (StEvent)" << mStEvent->fttCollection()->points().size() << endm; + } } LOG_INFO << "SETUP START" << endm; // setup the datasets / makers + + mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); if(mMuDstMaker) { mMuDst = mMuDstMaker->muDst(); mMuForwardTrackCollection = mMuDst->muFwdTrackCollection(); mMuFcsCollection = mMuDst->muFcsCollection(); + if (mMuDst->event()) + mTreeData.header.run = mMuDst->event()->runNumber(); if (mMuForwardTrackCollection){ LOG_DEBUG << "Number of StMuFwdTracks: " << mMuForwardTrackCollection->numberOfFwdTracks() << endm; } + else{ + LOG_DEBUG << "No muFwdTrackCollection " << endm; + } } else { LOG_DEBUG << "No StMuDstMaker found: " << mMuDstMaker << endm; } - mFcsDb = static_cast(GetDataSet("fcsDb")); + mFcsDb = static_cast(GetDataSet("fcsDb")); mFwdTrackMaker = (StFwdTrackMaker*) GetMaker( "fwdTrack" ); if (!mFwdTrackMaker) { LOG_WARN << "No StFwdTrackMaker found, skipping StFwdQAMaker" << endm; // return kStOk; } - mTreeData.header.run = mMuDst->event()->runNumber(); + LOG_DEBUG << "SETUP COMPLETE" << endm; + ProcessFwdTracks(); + ProcessFwdMuTracks(); - auto muFstCollection = mMuDst->muFstCollection(); - if ( muFstCollection ){ - LOG_DEBUG << "MuDst has #fst hits: " << muFstCollection->numberOfHits() << endm; - for ( size_t i = 0; i < muFstCollection->numberOfHits(); i++ ){ - StMuFstHit * h = muFstCollection->getHit(i); - mTreeData.fstPoints.add( h ); - } - } FillMcTracks(); - FillTracks(); - FillFstPoints(); + FillTracks(); //maybe not running + FillFstPoints(); //no fst FillFttClusters(); FillFcsStMuDst(); mTree->Fill(); + return kStOk; } void StFwdQAMaker::Clear(const Option_t *opts) { @@ -190,36 +267,10 @@ void StFwdQAMaker::FillFstPoints(){ return; } - // size_t numFwdHitsPrior = mFwdHitsFst.size(); LOG_INFO << "Loading " << fst->numberOfHits() << " StMuFstHits" << endm; - // TMatrixDSym hitCov3(3); for ( unsigned int index = 0; index < fst->numberOfHits(); index++){ StMuFstHit * muFstHit = fst->getHit( index ); mTreeData.fstPoints.add( muFstHit ); - - - // float vR = muFstHit->localPosition(0); - // float vPhi = muFstHit->localPosition(1); - // float vZ = muFstHit->localPosition(2); - - // const float dz0 = fabs( vZ - mFstZFromGeom[0] ); - // const float dz1 = fabs( vZ - mFstZFromGeom[1] ); - // const float dz2 = fabs( vZ - mFstZFromGeom[2] ); - // static const float fstThickness = 2.0; // thickness in cm between inner and outer on sigle plane - - // // assign disk according to which z value the hit has, within the z-plane thickness - // int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); - - // float x0 = vR * cos( vPhi ); - // float y0 = vR * sin( vPhi ); - // hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); - - // LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; - // mFstHits.push_back( TVector3( x0, y0, vZ) ); - - // // we use d+4 so that both FTT and FST start at 4 - // mFwdHitsFst.push_back(FwdHit(count++, x0, y0, vZ, d+4, 0, hitCov3, nullptr)); - // count++; } // index } @@ -244,6 +295,8 @@ void StFwdQAMaker::FillTracks() { break; } } + } else { + LOG_WARN << "No StMuFwdTrackCollection found" << endm; } LOG_DEBUG << "TRACKS COMPLETE" << endm; } @@ -273,7 +326,7 @@ void StFwdQAMaker::FillFcsStMuDst( ) { } else if ( clu->detectorId() == kFcsHcalNorthDetId || clu->detectorId() == kFcsHcalSouthDetId ){ LOG_INFO << "Adding HCAL Cluster to FwdTree" << endm; mTreeData.hcal.add( cluSTAR ); - } + } delete cluSTAR; } @@ -330,4 +383,325 @@ void StFwdQAMaker::FillFttClusters(){ mTreeData.fttPoints.add( c ); } } + else{ + LOG_INFO << "no muFttCollection " << endm; + } +} + +//==================================================adding new function + +void StFwdQAMaker::ProcessFwdTracks( ){ + // This is an example of how to process fwd track collection + LOG_DEBUG << "StFwdAnalysisMaker::ProcessFwdTracks" << endm; + StEvent *stEvent = static_cast(GetInputDS("StEvent")); + if (!stEvent) + return; + + if (stEvent){ + StFttCollection *fttCol = stEvent->fttCollection(); + if (fttCol){ + LOG_DEBUG << "The Ftt Collection has " << fttCol->numberOfPoints() << " points" << endm; + } + } + StFwdTrackCollection * ftc = stEvent->fwdTrackCollection(); + if (!ftc) { + LOG_DEBUG << "Forward Track Collection is not present" << endm; + return; + } + + LOG_DEBUG << "Checking FcsCollection" << endm; + StFcsCollection *fcs = stEvent->fcsCollection(); + if (!fcs) return; + + StFcsDb *mFcsDb = static_cast(GetDataSet("fcsDb")); + + size_t fwdMultEcalMatch = 0; + size_t fwdMultHcalMatch = 0; + size_t fwdMultFST = 0; + + LOG_INFO << "FwdTrackCollection has: " << ftc->tracks().size() << " tracks" << endm; + + getHist( "fwdMultAll" )->Fill( ftc->tracks().size() ); + + // Cluster info (independen t of tracks) + size_t fwdMultEcalClusters = 0; + size_t fwdMultHcalClusters = 0; + for ( int iDet = 0; iDet < 4; iDet++ ){ + for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ + StFcsCluster * clu = fcs->clusters(iDet)[i]; + + if ( iDet < 2 ){ + fwdMultEcalClusters++; + getHist( "ecalEnergy" )->Fill( clu->energy() ); + } else if ( iDet < 4 ){ + fwdMultHcalClusters++; + getHist( "hcalEnergy" )->Fill( clu->energy() ); + } + } + } + + getHist( "fwdMultEcalClusters" )->Fill( fwdMultEcalClusters ); + getHist( "fwdMultHcalClusters" )->Fill( fwdMultHcalClusters ); + + + size_t nGood = 0; + size_t nFailed = 0; + for ( auto fwdTrack : ftc->tracks() ){ + if ( !fwdTrack->didFitConvergeFully() ) { + nFailed++; + continue; + } + nGood++; + LOG_DEBUG << TString::Format("StFwdTrack[ nProjections=%lu, nFTTSeeds=%lu, nFSTSeeds=%lu, mPt=%f ]", fwdTrack->mProjections.size(), fwdTrack->mFTTPoints.size(), fwdTrack->mFSTPoints.size(), fwdTrack->momentum().perp()) << endm; + LOG_DEBUG << "track fit momentum " << TString::Format( "(pt=%f, eta=%f, phi=%f)", fwdTrack->momentum().perp(), fwdTrack->momentum().pseudoRapidity(), fwdTrack->momentum().phi() ) << endm; + LOG_DEBUG << "StFwdTrack has " << fwdTrack->ecalClusters().size() << " ecal matches" << endm; + LOG_DEBUG << "StFwdTrack has " << fwdTrack->hcalClusters().size() << " hcal matches" << endm; + + getHist("ecalMatchPerTrack")->Fill( fwdTrack->ecalClusters().size() ); + getHist("hcalMatchPerTrack")->Fill( fwdTrack->hcalClusters().size() ); + + getHist( "nHitsFit" )->Fill( fwdTrack->numberOfFitPoints() ); + + if (fwdTrack->mFSTPoints.size() > 0){ + fwdMultFST ++; + } + + getHist("eta")->Fill( fwdTrack->momentum().pseudoRapidity() ); + getHist("phi")->Fill( fwdTrack->momentum().phi() ); + getHist("pt")->Fill( fwdTrack->momentum().perp() ); + + getHist("charge")->Fill( fwdTrack->charge() ); + + // ecal proj + int detId = kFcsWcalId; + TVector3 ecalXYZ; + TVector3 ecapP; + + StFwdTrackProjection ecalProj = fwdTrack->getProjectionFor( detId, 0 ); + StFwdTrackProjection hcalProj = fwdTrack->getProjectionFor( kFcsHcalId, 0 ); + LOG_DEBUG << "EcalProj z= " << ecalProj.mXYZ.z() << endm; + LOG_DEBUG << "HcalProj z= " << hcalProj.mXYZ.z() << endm; + LOG_DEBUG << "EcalProj Mom" << TString::Format( "(pt=%f, eta=%f, phi=%f)", ecalProj.mMom.perp(), ecalProj.mMom.pseudoRapidity(), ecalProj.mMom.phi() ) << endm; + + for ( size_t iEcal = 0; iEcal < fwdTrack->ecalClusters().size(); iEcal++ ){ + StFcsCluster *clu = fwdTrack->ecalClusters()[iEcal]; + LOG_DEBUG << "Ecal clu detId = " << clu->detectorId() << endm; + getHist("matchedEcalEnergy")->Fill( clu->energy() ); + + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); + float dx = ecalProj.mXYZ.x() - xyz.x(); + float dy = ecalProj.mXYZ.y() - xyz.y(); + float dr = sqrt(dx*dx + dy*dy); + getHist("matchedEcaldX")->Fill( dx ); + getHist("matchedEcaldY")->Fill( dy ); + getHist("matchedEcaldR")->Fill( dr ); + } + + if (ecalProj.mXYZ.z() > 500){ + double mindR = 999; + StFcsCluster * cclu = nullptr; // closet cluster + for ( int iDet = 0; iDet < 2; iDet++ ){ + for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ + StFcsCluster * clu = fcs->clusters(iDet)[i]; + + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); + getHist("ecalXY")->Fill( xyz.x(), xyz.y() ); + + float dx = ecalProj.mXYZ.x() - xyz.x(); + float dy = ecalProj.mXYZ.y() - xyz.y(); + float dr = sqrt(dx*dx + dy*dy); + + if ( fabs(dy) < 25 ) + getHist( "ecaldX" )->Fill( dx ); + if ( fabs(dx) < 25 ) + getHist( "ecaldY" )->Fill( dy ); + getHist( "ecaldR" )->Fill( dr ); + if ( dr < mindR ){ + mindR = dr; + cclu = clu; + } + + getHist( "trkEcalX" ) -> Fill( ecalProj.mXYZ.x(), xyz.x() ); + getHist( "trkEcalY" ) -> Fill( ecalProj.mXYZ.y(), xyz.y() ); + + } + } + getHist( "ecalMindR" )->Fill( mindR ); + if (cclu){ + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(cclu->detectorId(), cclu->x(), cclu->y()); + getHist( "trkEcalMinX" ) -> Fill( ecalProj.mXYZ.x(), xyz.x() ); + getHist( "trkEcalMinY" ) -> Fill( ecalProj.mXYZ.y(), xyz.y() ); + } + } + + if (hcalProj.mXYZ.z() > 500){ + + double mindR = 999; + StFcsCluster * cclu = nullptr; + for ( int iDet = 2; iDet < 4; iDet++ ){ + for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ + StFcsCluster * clu = fcs->clusters(iDet)[i]; + if (!clu) continue; + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); + getHist("hcalXY")->Fill( xyz.x(), xyz.y() ); + + float dx = hcalProj.mXYZ.x() - xyz.x(); + float dy = hcalProj.mXYZ.y() - xyz.y(); + float dr = sqrt(dx*dx + dy*dy); + + if ( fabs(dy) < 25 ){ + getHist( "hcaldX" )->Fill( dx ); + getHist( "hcaldXdNFit" )->Fill( dx, fwdTrack->numberOfFitPoints() ); + + } + if ( fabs(dx) < 25 ){ + getHist( "hcaldY" )->Fill( dy ); + getHist( "hcaldYdNFit" )->Fill( dy, fwdTrack->numberOfFitPoints() ); + } + getHist( "hcaldR" )->Fill( dr ); + + if ( dr < mindR ){ + mindR = dr; + cclu = clu; + } + + getHist( "trkHcalX" ) -> Fill( hcalProj.mXYZ.x(), xyz.x() ); + getHist( "trkHcalY" ) -> Fill( hcalProj.mXYZ.y(), xyz.y() ); + } + } + getHist( "hcalMindR" )->Fill( mindR ); + if (cclu){ + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(cclu->detectorId(), cclu->x(), cclu->y()); + getHist( "trkHcalMinX" ) -> Fill( hcalProj.mXYZ.x(), xyz.x() ); + getHist( "trkHcalMinY" ) -> Fill( hcalProj.mXYZ.y(), xyz.y() ); + } + } + + if (fwdTrack->ecalClusters().size() > 0) + fwdMultEcalMatch++; + if (fwdTrack->hcalClusters().size() > 0) + fwdMultHcalMatch++; + + } // Loop ftc->tracks() + + getHist( "fwdMultGood" )->Fill( nGood ); + getHist( "fwdMultFailed" )->Fill( nFailed ); + getHist("fwdMultFST")->Fill( fwdMultFST ); + getHist("fwdMultHcalMatch")->Fill( fwdMultHcalMatch ); + getHist("fwdMultEcalMatch")->Fill( fwdMultEcalMatch ); + + LOG_INFO << "Found " << nFailed << " failed track fits out of " << ftc->tracks().size() << endm; +} // ProcessFwdTracks +//========================================================end of added function + + + +void StFwdQAMaker::ProcessFwdMuTracks( ){ + // This is an example of how to process fwd track collection + LOG_DEBUG << "StFwdAnalysisMaker::ProcessFwdMuTracks" << endm; + StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); + if(!mMuDstMaker) { + LOG_WARN << " No MuDstMaker ... bye-bye" << endm; + return; + } + StMuDst *mMuDst = mMuDstMaker->muDst(); + if(!mMuDst) { + LOG_WARN << " No MuDst ... bye-bye" << endm; + return; + } + StMuFwdTrackCollection * ftc = mMuDst->muFwdTrackCollection(); + if (!ftc) return; + + StMuFcsCollection *fcs = mMuDst->muFcsCollection(); + if (!fcs) return; + + LOG_INFO << "Number of StMuFwdTracks: " << ftc->numberOfFwdTracks() << endl; + + StFcsDb *mFcsDb = static_cast(GetDataSet("fcsDb")); + + size_t fwdMultFST = 0; + size_t fwdMultEcalMatch = 0; + size_t fwdMultHcalMatch = 0; + + for ( size_t iTrack = 0; iTrack < ftc->numberOfFwdTracks(); iTrack++ ){ + StMuFwdTrack * muFwdTrack = ftc->getFwdTrack( iTrack ); + // LOG_DEBUG << TString::Format("StMuFwdTrack[ nProjections=%lu, nFTTSeeds=%lu, nFSTSeeds=%lu, mPt=%f ]", muFwdTrack->mProjections.size(), muFwdTrack->mFTTPoints.size(), muFwdTrack->mFSTPoints.size(), muFwdTrack->momentum().Pt()) << endm; + + LOG_DEBUG << "StMuFwdTrack has " << muFwdTrack->mEcalClusters.GetEntries() << " Ecal matched" << endm; + LOG_DEBUG << "StMuFwdTrack has " << muFwdTrack->mHcalClusters.GetEntries() << " Hcal matched" << endm; + + getHist("eta")->Fill( muFwdTrack->momentum().Eta() ); + getHist("phi")->Fill( muFwdTrack->momentum().Phi() ); + + if (muFwdTrack->mFSTPoints.size() > 0){ + fwdMultFST ++; + } + + if (muFwdTrack->mEcalClusters.GetEntries() > 0) + fwdMultEcalMatch++; + if (muFwdTrack->mHcalClusters.GetEntries() > 0) + fwdMultHcalMatch++; + + + // ecal proj + int detId = kFcsWcalId; + TVector3 ecalXYZ; + TVector3 ecapP; + + StMuFwdTrackProjection ecalProj; + bool foundEcalProj = muFwdTrack->getProjectionFor( detId, ecalProj, 0 ); + + if (foundEcalProj){ + for( size_t i = 0; i < fcs->numberOfClusters(); i++){ + StMuFcsCluster * clu = fcs->getCluster(i); + + if ( clu->detectorId() > 1 ) continue; + + if ( clu->energy() < 1 ) continue; + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); + + float dx = ecalProj.mXYZ.X() - xyz.x(); + float dy = ecalProj.mXYZ.Y() - xyz.y(); + float dr = sqrt(dx*dx + dy*dy); + + getHist( "ecaldX" )->Fill( dx ); + getHist( "ecaldY" )->Fill( dy ); + getHist( "ecaldR" )->Fill( dr ); + + getHist( "trkEcalX" ) -> Fill( ecalProj.mXYZ.X(), xyz.x() ); + + } // i + } // foundEcalProj + + + for ( int i = 0; i < muFwdTrack->mEcalClusters.GetEntries(); i++ ){ + auto c = (StMuFcsCluster*) muFwdTrack->mEcalClusters.At(i); + if (!c) continue; + getHist("ecalEnergy")->Fill( c->energy() ); + + LOG_DEBUG << "eCal Cluster detId = " << c->detectorId() << endm; + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(c->detectorId(), c->x(), c->y()); + getHist("ecalXY")->Fill( xyz.x(), xyz.y() ); + + if (foundEcalProj){ + getHist("matchedEcaldX")->Fill( ecalProj.mXYZ.X() - xyz.x() ); + } + } // i + + getHist("ecalMatchPerTrack")->Fill( muFwdTrack->mEcalClusters.GetEntries() ); + getHist("hcalMatchPerTrack")->Fill( muFwdTrack->mHcalClusters.GetEntries() ); + + for ( int i = 0; i < muFwdTrack->mHcalClusters.GetEntries(); i++ ){ + auto c = (StMuFcsCluster*) muFwdTrack->mHcalClusters.At(i); + if (!c) continue; + getHist("hcalEnergy")->Fill( c->energy() ); + + getHist("hcalXY")->Fill( c->x(), c->y() ); + } // i + } // iTrack + + getHist("fwdMult")->Fill( ftc->numberOfFwdTracks() ); + getHist("fwdMultFST")->Fill( fwdMultFST ); + getHist("fwdMultHcalMatch")->Fill( fwdMultHcalMatch ); + getHist("fwdMultEcalMatch")->Fill( fwdMultEcalMatch ); } diff --git a/StRoot/StFwdTrackMaker/StFwdQAMaker.h b/StRoot/StFwdTrackMaker/StFwdQAMaker.h index bc60f98d5b4..b6f32db3724 100644 --- a/StRoot/StFwdTrackMaker/StFwdQAMaker.h +++ b/StRoot/StFwdTrackMaker/StFwdQAMaker.h @@ -15,6 +15,8 @@ #include "StEvent/StEnumerations.h" #include "StThreeVectorD.hh" +#include + class StMuFwdTrack; class StMuFwdTrackProjection; class ForwardTracker; @@ -198,6 +200,13 @@ class StFwdQAMaker : public StMaker { void FillTracks(); void FillMcTracks(); + void ProcessFwdTracks(); + void ProcessFwdMuTracks(); + + void setMuDstInput() { mAnalyzeMuDst = true; } + void setLocalOutputFile( TString f ) { mLocalOutputFile = f; } + void setTreeFilename( TString f ) {mTreeFilename = f;} + protected: TFile *mTreeFile = nullptr; TTree *mTree = nullptr; @@ -211,6 +220,32 @@ class StFwdQAMaker : public StMaker { StFwdTrackMaker *mFwdTrackMaker = nullptr; StFcsDb *mFcsDb = nullptr; + +//========================================================= new stuff + std::map mHists; + + /** + * @brief Get the Hist object from the map + * - Additional check and safety for missing histograms + * @param n Histogram name + * @return TH1* histogram if found, otherwise a 'nil' histogram with one bin + */ + TH1* getHist( TString n ){ + if (mHists.count(n)) + return mHists[n]; + LOG_ERROR << "Attempting to access non-existing histogram" << endm; + return new TH1F( "NULL", "NULL", 1, 0, 1 ); // returning nullptr can lead to seg fault, this fails softly + } + + /** + * @brief Control whether the analysis uses StEvent (default) or MuDst as input + * + */ + bool mAnalyzeMuDst = false; + TString mLocalOutputFile; + TString mTreeFilename; +//====================================================== end new stuff + }; diff --git a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx index a2881f3f660..4e1d6d39fa4 100644 --- a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx +++ b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx @@ -7,11 +7,10 @@ #include "KiTrack/IHit.h" #include "GenFit/Track.h" -#include "GenFit/GFRaveVertexFactory.h" #include "TMath.h" -#include +#include #include #include #include @@ -26,6 +25,8 @@ #include "StEvent/StRnDHit.h" #include "StEvent/StRnDHitCollection.h" #include "StEvent/StTrack.h" +#include "StEvent/StBTofCollection.h" +#include "StEvent/StBTofHeader.h" #include "StEvent/StTrackGeometry.h" #include "StEvent/StTrackNode.h" #include "StEvent/StPrimaryVertex.h" @@ -44,6 +45,9 @@ #include "StEventUtilities/StEventHelper.h" +#include "StMcEvent/StMcEvent.hh" +#include "StMcEvent/StMcVertex.hh" + #include "tables/St_g2t_fts_hit_Table.h" #include "tables/St_g2t_track_Table.h" #include "tables/St_g2t_vertex_Table.h" @@ -68,15 +72,16 @@ #include "StEvent/StFwdTrack.h" #include "GenFit/AbsMeasurement.h" +#include "StMuDSTMaker/COMMON/StMuDstMaker.h" +#include "StMuDSTMaker/COMMON/StMuDst.h" +#include "StMuDSTMaker/COMMON/StMuFstCollection.h" +#include "StMuDSTMaker/COMMON/StMuFstHit.h" +#include "StMuDSTMaker/COMMON/StMuPrimaryVertex.h" -FwdSystem* FwdSystem::sInstance = nullptr; -TMVA::Reader * BDTCrit2::reader = nullptr; -float BDTCrit2::Crit2_RZRatio = -999; -float BDTCrit2::Crit2_DeltaRho = -999; -float BDTCrit2::Crit2_DeltaPhi = -999; -float BDTCrit2::Crit2_StraightTrackRatio = -999; - +#include "sys/types.h" +#include "sys/sysinfo.h" +FwdSystem* FwdSystem::sInstance = nullptr; //_______________________________________________________________________________________ class GenfitUtils{ @@ -84,8 +89,6 @@ class GenfitUtils{ // For now, accept anything we are passed, no matter what it is or how bad it is template static bool accept( T ) { return true; } - - }; // GenfitUtils // Basic sanity cuts on genfit tracks @@ -112,10 +115,10 @@ template<> bool GenfitUtils::accept( genfit::Track *track ) } } - // Following line fails with an exception, because some tracks lack + // Following line fails with an exception, because some tracks lack // forward update, or prediction in fitter info at the first point // - // genfit::KalmanFitterInfo::getFittedState(bool) const of + // genfit::KalmanFitterInfo::getFittedState(bool) const of // GenFit/fitters/src/KalmanFitterInfo.cc:250 // Fitted state at the first point @@ -130,7 +133,7 @@ template<> bool GenfitUtils::accept( genfit::Track *track ) for ( ipoint = 0; ipoint < track->getNumPoints(); ipoint++ ) { first = track->getPointWithFitterInfo( ipoint ); if ( first ) break; - } + } // No points on the track have fit information if ( !first ) { @@ -158,7 +161,7 @@ class SiRasterizer { void setup(FwdTrackerConfig &_cfg) { cfg = _cfg; mRasterR = cfg.get("SiRasterizer:r", 3.0); - mRasterPhi = cfg.get("SiRasterizer:phi", 0.1); + mRasterPhi = cfg.get("SiRasterizer:phi", 0.004); } bool active() { @@ -191,13 +194,8 @@ class ForwardTracker : public ForwardTrackMaker { // Create the forward system... FwdSystem::sInstance = new FwdSystem(); - // make our quality plotter - mQualityPlotter = new QualityPlotter(mConfig); - mQualityPlotter->makeHistograms(mConfig.get("TrackFinder:nIterations", 1)); - // initialize the track fitter mTrackFitter = new TrackFitter(mConfig, geoCache); - mTrackFitter->setGenerateHistograms(genHistograms); mTrackFitter->setup(); ForwardTrackMaker::initialize( geoCache, genHistograms ); @@ -205,19 +203,10 @@ class ForwardTracker : public ForwardTrackMaker { void finish() { - if ( mGenHistograms ){ - mQualityPlotter->finish(); - writeEventHistograms(); - } - if (FwdSystem::sInstance){ delete FwdSystem::sInstance; FwdSystem::sInstance = 0; } - if (mQualityPlotter){ - delete mQualityPlotter; - mQualityPlotter = 0; - } if (mTrackFitter){ delete mTrackFitter; mTrackFitter= 0; @@ -226,8 +215,8 @@ class ForwardTracker : public ForwardTrackMaker { }; //________________________________________________________________________ -StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mGenHistograms(false), mGenTree(false), mForwardTracker(nullptr), mForwardData(nullptr){ - SetAttr("useFtt",1); // Default Ftt on +StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mForwardTracker(nullptr), mForwardData(nullptr), mGeoCache(""){ + SetAttr("useFtt",1); // Default Ftt on SetAttr("useFst",1); // Default Fst on SetAttr("useFcs",1); // Default Fcs on SetAttr("config", "config.xml"); // Default configuration file (user may override before Init()) @@ -235,39 +224,12 @@ StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mGenHistograms(false), }; int StFwdTrackMaker::Finish() { - - auto prevDir = gDirectory; - if ( mGenHistograms ) { - - // output file name - string name = mFwdConfig.get("Output:url", "fwdTrackerOutput.root"); - LOG_INFO << "Saving StFwdTrackMaker Histograms to ROOT file: " << name << endm; - TFile *fOutput = new TFile(name.c_str(), "RECREATE"); - fOutput->cd(); - - fOutput->mkdir("StFwdTrackMaker"); - fOutput->cd("StFwdTrackMaker"); - for (auto nh : mHistograms) { - nh.second->SetDirectory(gDirectory); - nh.second->Write(); - } - fOutput->cd(""); - } - mForwardTracker->finish(); - - prevDir->cd(); - - if (mGenTree) { - mTreeFile->cd(); - mTree->Write(); - mTreeFile->Write(); - } return kStOk; } void StFwdTrackMaker::LoadConfiguration() { - if (mConfigFile.length() < 5){ + if (mConfigFile.length() < 5){ LOG_INFO << "Forward Tracker is using default config for "; if ( defaultConfig == defaultConfigData ){ LOG_INFO << " DATA" << endm; @@ -284,226 +246,46 @@ void StFwdTrackMaker::LoadConfiguration() { //________________________________________________________________________ int StFwdTrackMaker::Init() { - if ( !configLoaded ){ LoadConfiguration(); } - if (mGenTree) { - mTreeFile = new TFile("fwdtree.root", "RECREATE"); - mTree = new TTree("fwd", "fwd tracking tree"); - mTree->Branch("fttN", &mTreeData. fttN, "fttN/I"); - mTree->Branch("fttX", &mTreeData. fttX ); - mTree->Branch("fttY", &mTreeData. fttY ); - mTree->Branch("fttZ", &mTreeData. fttZ ); - - mTree->Branch("fttTrackId", &mTreeData. fttTrackId ); - mTree->Branch("fttVolumeId", &mTreeData. fttVolumeId ); - mTree->Branch("fttPt", &mTreeData. fttPt ); - mTree->Branch("fttVertexId", &mTreeData. fttVertexId ); - - mTree->Branch("fstN", &mTreeData. fstN, "fstN/I"); - mTree->Branch("fstX", &mTreeData. fstX ); - mTree->Branch("fstY", &mTreeData. fstY ); - mTree->Branch("fstZ", &mTreeData. fstZ ); - mTree->Branch("fstTrackId", &mTreeData. fstTrackId ); - - mTree->Branch("fcsN", &mTreeData. fcsN, "fcsN/I"); - mTree->Branch("fcsX", &mTreeData. fcsX ); - mTree->Branch("fcsY", &mTreeData. fcsY ); - mTree->Branch("fcsZ", &mTreeData. fcsZ ); - mTree->Branch("fcsDet", &mTreeData. fcsDet ); - - // mc tracks - mTree->Branch("mcN", &mTreeData. mcN, "mcN/I"); - mTree->Branch("mcPt", &mTreeData. mcPt ); - mTree->Branch("mcEta", &mTreeData. mcEta ); - mTree->Branch("mcPhi", &mTreeData. mcPhi ); - mTree->Branch("mcCharge", &mTreeData. mcCharge ); - mTree->Branch("mcVertexId", &mTreeData. mcVertexId ); - - // mcverts - mTree->Branch("vmcN", &mTreeData. vmcN, "vmcN/I"); - mTree->Branch("vmcX", &mTreeData. vmcX ); - mTree->Branch("vmcY", &mTreeData. vmcY ); - mTree->Branch("vmcZ", &mTreeData. vmcZ ); - - // rcverts - mTree->Branch("vrcN", &mTreeData. vrcN, "vrcN/I"); - mTree->Branch("vrcX", &mTreeData. vrcX ); - mTree->Branch("vrcY", &mTreeData. vrcY ); - mTree->Branch("vrcZ", &mTreeData. vrcZ ); - - // rc tracks - mTree->Branch("rcN", &mTreeData. rcN, "rcN/I"); - mTree->Branch("rcPt", &mTreeData. rcPt ); - mTree->Branch("rcEta", &mTreeData. rcEta ); - mTree->Branch("rcPhi", &mTreeData. rcPhi ); - mTree->Branch("rcCharge", &mTreeData. rcCharge ); - mTree->Branch("rcTrackId", &mTreeData. rcTrackId ); - mTree->Branch("rcNumFST", &mTreeData. rcNumFST ); - mTree->Branch("rcNumFTT", &mTreeData. rcNumFTT ); - mTree->Branch("rcNumPV", &mTreeData. rcNumPV ); - mTree->Branch("rcQuality", &mTreeData. rcQuality ); - - mTree->Branch("thdN", &mTreeData. thdN, "thdN/I"); - mTree->Branch("thdX", &mTreeData. thdX ); - mTree->Branch("thdY", &mTreeData. thdY ); - mTree->Branch("thaX", &mTreeData. thaX ); - mTree->Branch("thaY", &mTreeData. thaY ); - mTree->Branch("thaZ", &mTreeData. thaZ ); - - // track projections - mTree->Branch("tprojN", &mTreeData. tprojN, "tprojN/I"); - mTree->Branch("tprojIdD", &mTreeData. tprojIdD); - mTree->Branch("tprojIdT", &mTreeData. tprojIdT); - mTree->Branch("tprojX", &mTreeData. tprojX); - mTree->Branch("tprojY", &mTreeData. tprojY); - mTree->Branch("tprojZ", &mTreeData. tprojZ); - mTree->Branch("tprojPx", &mTreeData. tprojPx); - mTree->Branch("tprojPy", &mTreeData. tprojPy); - mTree->Branch("tprojPz", &mTreeData. tprojPz); - - std::string path = "TrackFinder.Iteration[0].SegmentBuilder"; - std::vector paths = mFwdConfig.childrenOf(path); - - if (mTreeData.saveCrit){ - for (string p : paths) { - string name = mFwdConfig.get(p + ":name", ""); - mTreeData.Crits[name]; // create the entry - mTree->Branch(name.c_str(), &mTreeData.Crits[name]); - mTree->Branch((name + "_trackIds").c_str(), &mTreeData.CritTrackIds[name]); - - if ( name == "Crit2_RZRatio" ){ - string n = name + "_x1"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_y1"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_z1"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_x2"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_y2"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_z2"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_h1"; - mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); - n = name + "_h2"; - mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); - n = name + "_h3"; - mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); - } - - if ( name == "Crit2_BDT" ){ - string n = name + "_DeltaPhi"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - n = name + "_DeltaRho"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - n = name + "_RZRatio"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - n = name + "_StraightTrackRatio"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - } - } - - // Three hit criteria - path = "TrackFinder.Iteration[0].ThreeHitSegments"; - paths = mFwdConfig.childrenOf(path); - - for (string p : paths) { - string name = mFwdConfig.get(p + ":name", ""); - mTreeData.Crits[name]; // create the entry - mTree->Branch(name.c_str(), &mTreeData.Crits[name]); - mTree->Branch((name + "_trackIds").c_str(), &mTreeData.CritTrackIds[name]); - } - } - - mTree->SetAutoFlush(0); - } // gen tree - - - /// Instantiate and cache the geometry - GetDataBase("VmcGeometry"); + if ( mGeoCache == "" ){ + /// Instantiate and cache the geometry + GetDataBase("VmcGeometry"); + mGeoCache = GetChainOpt()->GetFileOut(); + if ( mGeoCache=="" ) + mGeoCache = GetChainOpt()->GetFileIn(); - - TString geoCache = GetChainOpt()->GetFileOut(); - if ( geoCache=="" ) - geoCache = GetChainOpt()->GetFileIn(); - - // Strip out @ symbol - geoCache = geoCache.ReplaceAll("@",""); - // Strip off the last extention in the geoCache - geoCache = geoCache( 0, geoCache.Last('.') ); - // Append geom.root to the extentionless geoCache - geoCache+=".geom.root"; - - // create an SiRasterizer in case we need it + // Strip out @ symbol + mGeoCache = mGeoCache.ReplaceAll("@",""); + // Strip off the last extention in the mGeoCache + mGeoCache = mGeoCache( 0, mGeoCache.Last('.') ); + // Append geom.root to the extentionless mGeoCache + mGeoCache+=".geom.root"; + } + // create an SiRasterizer in case we need it mSiRasterizer = std::shared_ptr( new SiRasterizer(mFwdConfig)); mForwardTracker = std::shared_ptr(new ForwardTracker( )); mForwardTracker->setConfig(mFwdConfig); - // only save criteria values if we are generating a tree. - mForwardTracker->setSaveCriteriaValues(mGenTree); + // in production we disable crit saving. + mForwardTracker->setSaveCriteriaValues(false); mForwardData = std::shared_ptr(new FwdDataSource()); mForwardTracker->setData(mForwardData); - mForwardTracker->initialize( geoCache, mGenHistograms ); - - if ( mGenHistograms ){ - mHistograms["fwdVertexZ"] = new TH1D("fwdVertexZ", "FWD Vertex (RAVE);z", 1000, -50, 50); - mHistograms["fwdVertexXY"] = new TH2D("fwdVertexXY", "FWD Vertex (RAVE);x;y", 100, -1, 1, 100, -1, 1); - mHistograms["fwdVertexDeltaZ"] = new TH2D("fwdVertexDeltaZ", "FWD Vertex - MC Vertex;#Delta z", 100, -1, 1, 100, -1, 1); - - mHistograms["McEventEta"] = new TH1D("McEventEta", ";MC Track Eta", 1000, -5, 5); - mHistograms["McEventPt"] = new TH1D("McEventPt", ";MC Track Pt (GeV/c)", 1000, 0, 10); - mHistograms["McEventPhi"] = new TH1D("McEventPhi", ";MC Track Phi", 1000, 0, 6.2831852); - - // these are tracks within 2.5 < eta < 4.0 - mHistograms["McEventFwdEta"] = new TH1D("McEventFwdEta", ";MC Track Eta", 1000, -5, 5); - mHistograms["McEventFwdPt"] = new TH1D("McEventFwdPt", ";MC Track Pt (GeV/c)", 1000, 0, 10); - mHistograms["McEventFwdPhi"] = new TH1D("McEventFwdPhi", ";MC Track Phi", 1000, 0, 6.2831852); + mForwardTracker->initialize( mGeoCache, false ); - // create mHistograms - mHistograms["nMcTracks"] = new TH1I("nMcTracks", ";# MC Tracks/Event", 1000, 0, 1000); - mHistograms["nMcTracksFwd"] = new TH1I("nMcTracksFwd", ";# MC Tracks/Event", 1000, 0, 1000); - mHistograms["nMcTracksFwdNoThreshold"] = new TH1I("nMcTracksFwdNoThreshold", ";# MC Tracks/Event", 1000, 0, 1000); - - mHistograms["nHitsSTGC"] = new TH1I("nHitsSTGC", ";# STGC Hits/Event", 1000, 0, 1000); - mHistograms["nHitsFSI"] = new TH1I("nHitsFSI", ";# FSIT Hits/Event", 1000, 0, 1000); - - mHistograms["stgc_volume_id"] = new TH1I("stgc_volume_id", ";stgc_volume_id", 50, 0, 50); - mHistograms["fsi_volume_id"] = new TH1I("fsi_volume_id", ";fsi_volume_id", 50, 0, 50); - - mHistograms["fsiHitDeltaR"] = new TH1F("fsiHitDeltaR", "FSI; delta r (cm); ", 500, -5, 5); - mHistograms["fsiHitDeltaPhi"] = new TH1F("fsiHitDeltaPhi", "FSI; delta phi; ", 500, -5, 5); - - // there are 4 stgc stations - for (int i = 0; i < 4; i++) { - mHistograms[TString::Format("stgc%dHitMap", i).Data()] = new TH2F(TString::Format("stgc%dHitMap", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - - mHistograms[TString::Format("stgc%dHitMapPrim", i).Data()] = new TH2F(TString::Format("stgc%dHitMapPrim", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - mHistograms[TString::Format("stgc%dHitMapSec", i).Data()] = new TH2F(TString::Format("stgc%dHitMapSec", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - } - - // There are 3 silicon stations - for (int i = 0; i < 3; i++) { - mHistograms[TString::Format("fsi%dHitMap", i).Data()] = new TH2F(TString::Format("fsi%dHitMap", i), TString::Format("FSI Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - mHistograms[TString::Format("fsi%dHitMapZ", i).Data()] = new TH2F(TString::Format("fsi%dHitMapZ", i), TString::Format("FSI Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - - mHistograms[TString::Format("fsi%dHitMapR", i).Data()] = new TH1F(TString::Format("fsi%dHitMapR", i), TString::Format("FSI Layer %d; r (cm); ", i), 500, 0, 50); - mHistograms[TString::Format("fsi%dHitMapPhi", i).Data()] = new TH1F(TString::Format("fsi%dHitMapPhi", i), TString::Format("FSI Layer %d; phi; ", i), 320, 0, TMath::Pi() * 2 + 0.1); - } - - } // mGenHistograms - LOG_DEBUG << "StFwdTrackMaker::Init" << endm; + // geometry should be available from here (mForwardTracker will initialize cache if needed) + if (gGeoManager) { + FwdGeomUtils fwdGeoUtils( gGeoManager ); + // get the z-locations from geometry model and fallback to the defaults + auto fstZ = fwdGeoUtils.fstZ( {151.750000, 165.248001, 178.781006} ); + mFstZFromGeom.assign( fstZ.begin(), fstZ.end() ); + auto fttZ = fwdGeoUtils.fttZ( {280.904999, 303.704987, 326.605011, 349.404999} ); + mFttZFromGeom.assign( fttZ.begin(), fttZ.end() ); + } return kStOK; }; @@ -570,68 +352,84 @@ void StFwdTrackMaker::loadFttHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdD StEvent *event = (StEvent *)GetDataSet("StEvent"); string fttFromSource = mFwdConfig.get( "Source:ftt", "" ); - if (!event){ + if (!event){ LOG_ERROR << "No StEvent, cannot load Ftt Data" << endm; return; } - // Load GEANT hits directly if requested - if ( "GEANT" == fttFromSource ) { - LOG_DEBUG << "Loading sTGC hits directly from GEANT hits" << endm; - loadFttHitsFromGEANT( mcTrackMap, hitMap, count ); - return; - } - StFttCollection *col = event->fttCollection(); // From Data if ( col || "DATA" == fttFromSource ) { loadFttHitsFromStEvent( mcTrackMap, hitMap, count ); return; } + + // Load GEANT hits directly if requested + if ( true ) { + LOG_DEBUG << "Try loading sTGC hits directly from GEANT hits" << endm; + loadFttHitsFromGEANT( mcTrackMap, hitMap, count ); + return; + } } // loadFttHits void StFwdTrackMaker::loadFttHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ LOG_DEBUG << "Loading FTT Hits from Data" << endm; StEvent *event = (StEvent *)GetDataSet("StEvent"); StFttCollection *col = event->fttCollection(); - - mTreeData.fttN = 0; + size_t numFwdHitsPrior = mFwdHitsFtt.size(); if ( col && col->numberOfPoints() > 0 ){ LOG_DEBUG << "The Ftt Collection has " << col->numberOfPoints() << " points" << endm; TMatrixDSym hitCov3(3); - const double sigXY = 0.2; // + const double sigXY = 0.2; // hitCov3(0, 0) = sigXY * sigXY; hitCov3(1, 1) = sigXY * sigXY; hitCov3(2, 2) = 4; // unused since they are loaded as points on plane + static const double mm_to_cm = 0.1; for ( auto point : col->points() ){ - - FwdHit *hit = new FwdHit(count++, point->xyz().x()/10.0, point->xyz().y()/10.0, point->xyz().z(), -point->plane(), 0, hitCov3, nullptr); - mFttHits.push_back( TVector3( point->xyz().x()/10.0, point->xyz().y()/10.0, point->xyz().z() ) ); - if ( mGenHistograms ) { - mHistograms[TString::Format("stgc%dHitMapSec", point->plane()).Data()]->Fill(point->xyz().x()/10.0, point->xyz().y()/10.0); - } - // Add the hit to the hit map - hitMap[hit->getSector()].push_back(hit); - if (mGenTree && (unsigned)mTreeData.fttN < MAX_TREE_ELEMENTS) { - LOG_DEBUG << "FttPoint( " << TString::Format( "[plane=%d, quad=%d, nClu=%d]", point->plane(), point->quadrant(), point->nClusters() ) << point->xyz().x()/10.0 << ", " << point->xyz().y()/10.0 << ", " << point->xyz().z() << " )" << endm; - mTreeData.fttX.push_back( point->xyz().x()/10.0 ); - mTreeData.fttY.push_back( point->xyz().y()/10.0 ); - mTreeData.fttZ.push_back( point->xyz().z() ); - mTreeData.fttTrackId.push_back( 0 ); - mTreeData.fttVolumeId.push_back( point->plane() ); - mTreeData.fttPt.push_back( 0 ); - mTreeData.fttVertexId.push_back( 0 ); - mTreeData.fttN++; + float xcm = point->xyz().x()*mm_to_cm; + float ycm = point->xyz().y()*mm_to_cm; + float zcm = point->xyz().z(); + + // get the track id + int track_id = point->idTruth(); + shared_ptr mcTrack = nullptr; + if ( mcTrackMap.count(track_id) ) { + mcTrack = mcTrackMap[track_id]; + LOG_DEBUG << "Adding McTrack to FTT hit: " << track_id << endm; } - } - return; + mFwdHitsFtt.push_back(FwdHit(count++, // id + xcm, ycm, zcm, + -point->plane(), // volume id + kFttId, // detid + track_id, // track id + hitCov3, // covariance matrix + mcTrack) // mcTrack + ); + mFttHits.push_back( TVector3( xcm, ycm, zcm) ); + } // end of loop over points } else { LOG_DEBUG << "The Ftt Collection is EMPTY points" << endm; } - LOG_DEBUG << "Number of FTT in TTree: " << mTreeData.fttN << endm; + + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFtt.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFtt[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + // add to MC track map + if ( hit->getMcTrack() ){ + hit->getMcTrack()->addFttHit(hit); + } + } + + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FTT hits from StEvent" << endm; + } } void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ @@ -639,27 +437,22 @@ void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrack // STGC Hits St_g2t_fts_hit *g2t_stg_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_stg_hit"); - - mTreeData.fttN = 0; + size_t numFwdHitsPrior = mFwdHitsFtt.size(); if (!g2t_stg_hits){ - LOG_WARN << "geant/g2t_stg_hit is empty" << endm; + LOG_WARN << "geant/g2t_stg_hit is empty" << endm; return; } // make the Covariance Matrix once and then reuse TMatrixDSym hitCov3(3); - const double sigXY = 0.01; + const double sigXY = 0.02; hitCov3(0, 0) = sigXY * sigXY; hitCov3(1, 1) = sigXY * sigXY; - hitCov3(2, 2) = 1.0; // unused since they are loaded as points on plane + hitCov3(2, 2) = 0.1; // unused since they are loaded as points on plane int nstg = g2t_stg_hits->GetNRows(); LOG_DEBUG << "This event has " << nstg << " stg hits in geant/g2t_stg_hit " << endm; - if ( mGenHistograms ) { - mHistograms["nHitsSTGC"]->Fill(nstg); - } - bool filterGEANT = mFwdConfig.get( "Source:fttFilter", false ); for (int i = 0; i < nstg; i++) { @@ -675,152 +468,258 @@ void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrack if ( volume_id % 2 ==0 ) continue; - float x = git->x[0] + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso - float y = git->x[1] + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso + float x = git->x[0];// + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso + float y = git->x[1];// + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso float z = git->x[2]; - - - if (mGenTree && (unsigned)mTreeData.fttN < MAX_TREE_ELEMENTS) { - mTreeData.fttX.push_back( x ); - mTreeData.fttY.push_back( y ); - mTreeData.fttZ.push_back( z ); - mTreeData.fttTrackId.push_back( track_id ); - mTreeData.fttVolumeId.push_back( plane_id ); - mTreeData.fttPt.push_back( mcTrackMap[track_id]->mPt ); - mTreeData.fttVertexId.push_back( mcTrackMap[track_id]->mStartVertex ); - mTreeData.fttN++; - } else if ( mGenTree ){ - LOG_WARN << "Truncating hits in TTree output" << endm; + if (plane_id < 0 || plane_id >= 4) { + continue; } + mFwdHitsFtt.push_back( + FwdHit( + count++, // id + x, y, z, // position + -plane_id, // volume id + kFttId, // detid + track_id, // track id + hitCov3, // covariance matrix + mcTrackMap[track_id] // mcTrack + ) + ); + mFttHits.push_back( TVector3( x, y, z ) ); + } // loop on hits - if ( mGenHistograms ){ - mHistograms["stgc_volume_id"]->Fill(volume_id); - } + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFtt.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFtt[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); - if (plane_id < 4 && plane_id >= 0) { - if ( mGenHistograms ){ - mHistograms[TString::Format("stgc%dHitMap", plane_id).Data()]->Fill(x, y); - } - } else { - continue; + if ( dynamic_cast(hit)->_mcTrack ){ + dynamic_cast(hit)->_mcTrack->addFttHit(hit); } + } - // this rejects GEANT hits with eta -999 - do we understand this effect? - if ( filterGEANT ) { - if ( mcTrackMap[track_id] && fabs(mcTrackMap[track_id]->mEta) > 5.0 ){ - - if ( mGenHistograms ) - mHistograms[TString::Format("stgc%dHitMapSec", plane_id).Data()]->Fill(x, y); - continue; - } else if ( mcTrackMap[track_id] && fabs(mcTrackMap[track_id]->mEta) < 5.0 ){ - if ( mGenHistograms ) mHistograms[TString::Format("stgc%dHitMapPrim", plane_id).Data()]->Fill(x, y); - } - } + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from MuDst" << endm; + } - FwdHit *hit = new FwdHit(count++, x, y, z, -plane_id, track_id, hitCov3, mcTrackMap[track_id]); +} // loadFttHits - // Add the hit to the hit map - hitMap[hit->getSector()].push_back(hit); - mFttHits.push_back( TVector3( x, y, z ) ); +/** + * @brief Loads FST hits from various sources into the hitmap and McTrackMap (if availabale) + * + * Order of precedence: + * MuDst StMuFstCollection (Data) + * StEvent StFstHitCollection (Data or slowsim) + * StEvent StRndHitCollection (fast sim) + * GEANT St_g2t_fts_hit (starsim only) - note if rasterizer is active this takes priority over FastSim + * + * @param mcTrackMap : MC track map if running sim + * @param hitMap : FST hitmap to populate + * @param count : number of hits loaded + */ +int StFwdTrackMaker::loadFstHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap ){ + + int count = loadFstHitsFromMuDst(mcTrackMap, hitMap); + if ( count > 0 ) return count; // only load from one source at a time + + count += loadFstHitsFromStEvent(mcTrackMap, hitMap); + if ( count > 0 ) return count; // only load from one source at a time - // Add hit pointer to the track - if (mcTrackMap[track_id]){ - mcTrackMap[track_id]->addHit(hit); - } else { - LOG_ERROR << "Cannot find MC track for GEANT hit (FTT), track_id = " << track_id << endm; - } - } // loop on hits + bool siRasterizer = mFwdConfig.get( "SiRasterizer:active", false ); + + if ( !siRasterizer ) count += loadFstHitsFromStRnDHits( mcTrackMap, hitMap ); + if ( count > 0 ) return count; // only load from one source at a time + + return loadFstHitsFromGEANT( mcTrackMap, hitMap ); +} // loadFstHits + +int StFwdTrackMaker::loadFstHitsFromMuDst( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ + int count = 0; + StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); + if(!mMuDstMaker) { + LOG_WARN << " No MuDstMaker ... bye-bye" << endm; + return 0; + } + StMuDst *mMuDst = mMuDstMaker->muDst(); + if(!mMuDst) { + LOG_WARN << " No MuDst ... bye-bye" << endm; + return 0; + } - if (mGenTree){ - LOG_INFO << "Saving " << mTreeData.fttN << " hits in Tree" << endm; + StMuFstCollection * fst = mMuDst->muFstCollection(); + if (!fst) { + LOG_WARN << "No StMuFstCollection ... bye-bye" << endm; + return 0; } -} // loadFttHits -void StFwdTrackMaker::loadFstHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ + size_t numFwdHitsPrior = mFwdHitsFst.size(); + LOG_INFO << "Loading " << fst->numberOfHits() << " StMuFstHits" << endm; + TMatrixDSym hitCov3(3); + for ( unsigned int index = 0; index < fst->numberOfHits(); index++){ + StMuFstHit * muFstHit = fst->getHit( index ); + + float vR = muFstHit->localPosition(0); + float vPhi = muFstHit->localPosition(1); + float vZ = muFstHit->localPosition(2); + + const float dz0 = fabs( vZ - mFstZFromGeom[0] ); + const float dz1 = fabs( vZ - mFstZFromGeom[1] ); + const float dz2 = fabs( vZ - mFstZFromGeom[2] ); + static const float fstThickness = 2.0; // thickness in cm between inner and outer on sigle plane + + // assign disk according to which z value the hit has, within the z-plane thickness + int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); + + float x0 = vR * cos( vPhi ); + float y0 = vR * sin( vPhi ); + hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); + + LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; + mFstHits.push_back( TVector3( x0, y0, vZ) ); + + // we use d+4 so that both FTT and FST start at 4 + mFwdHitsFst.push_back( + FwdHit( + count++, // id + x0, y0, vZ, // position + d+4, // volume id + kFstId, // detid + 0, // track id + hitCov3, // covariance matrix + nullptr // mcTrack + ) + ); + } // index + + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFst.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + } + + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from MuDst" << endm; + } + + // TODO add to hitmap + return count; +} // loadFstHitsFromMuDst + +int StFwdTrackMaker::loadFstHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ + int count = 0; StEvent *event = (StEvent *)GetDataSet("StEvent"); + if (!event) { + LOG_WARN << "No StEvent, cannot load FST hits from StEvent StFstHitCollection" << endm; + return 0; + } + LOG_DEBUG << "Got StEvent, loading Fst Hits" << endm; StFstHitCollection *fstHitCollection = event->fstHitCollection(); + size_t numFwdHitsPrior = mFwdHitsFst.size(); - if ( fstHitCollection ){ + if ( fstHitCollection && fstHitCollection->numberOfHits() > 0){ // reuse this to store cov mat TMatrixDSym hitCov3(3); LOG_DEBUG << "StFstHitCollection is NOT NULL, loading hits" << endm; for ( unsigned int iw = 0; iw < kFstNumWedges; iw++ ){ StFstWedgeHitCollection * wc = fstHitCollection->wedge( iw ); - + if ( !wc ) continue; for ( unsigned int is = 0; is < kFstNumSensorsPerWedge; is++ ){ StFstSensorHitCollection * sc = wc->sensor( is ); - + if ( !sc ) continue; StSPtrVecFstHit fsthits = sc->hits(); - mTreeData.fstN = 0; for ( unsigned int ih = 0; ih < fsthits.size(); ih++ ){ float vR = fsthits[ih]->localPosition(0); float vPhi = fsthits[ih]->localPosition(1); float vZ = fsthits[ih]->localPosition(2); - const float dz0 = fabs( vZ - 151.75 ); - const float dz1 = fabs( vZ - 165.248 ); - const float dz2 = fabs( vZ - 178.781 ); - - int d = 0 * ( dz0 < 1.0 ) + 1 * ( dz1 < 1.0 ) + 2 * ( dz2 < 1.0 ); - + const float dz0 = fabs( vZ - mFstZFromGeom[0] ); + const float dz1 = fabs( vZ - mFstZFromGeom[1] ); + const float dz2 = fabs( vZ - mFstZFromGeom[2] ); + static const float fstThickness = 3.0; // thickness in cm between inner and outer on sigle plane + // assign disk according to which z value the hit has, within the z-plane thickness + int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); float x0 = vR * cos( vPhi ); float y0 = vR * sin( vPhi ); hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); - LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; + LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; mFstHits.push_back( TVector3( x0, y0, vZ) ); + int track_id = fsthits[ih]->idTruth(); + LOG_DEBUG << "FST Hit: idTruth = " << track_id << endm; + shared_ptr mcTrack = nullptr; + if ( mcTrackMap.count(track_id) ) { + mcTrack = mcTrackMap[track_id]; + LOG_DEBUG << "Adding McTrack to FST hit" << endm; + } - FwdHit *hit = new FwdHit(count++, x0, y0, vZ, d, 0, hitCov3, nullptr); - // Add the hit to the hit map - hitMap[hit->getSector()].push_back(hit); - - mTreeData.fstX.push_back( x0 ); - mTreeData.fstY.push_back( y0 ); - mTreeData.fstZ.push_back( vZ ); - - mTreeData.fstN++; + // we use d+4 so that both FTT and FST start at 4 + mFwdHitsFst.push_back( + FwdHit( + count++, // id + x0, y0, vZ, // position + d+4, // volume id + kFstId, // detid + track_id, // mc track id + hitCov3, // covariance matrix + mcTrack // mcTrack + ) + ); + // store a pointer to the original StFstHit + mFwdHitsFst.back()._hit = fsthits[ih]; } } // loop is } // loop iw - LOG_DEBUG << " FOUND " << mFstHits.size() << " FST HITS" << endm; - return; + LOG_DEBUG << " FOUND " << mFstHits.size() << " FST HITS in StFstHitCollection" << endm; } // fstHitCollection - - StRnDHitCollection *rndCollection = nullptr; - if (nullptr != event) { - rndCollection = event->rndHitCollection(); + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFst.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + // add to MC track map + if ( hit->getMcTrack() ){ + hit->getMcTrack()->addFstHit(hit); + } } - bool siRasterizer = mFwdConfig.get( "SiRasterizer:active", false ); - if ( siRasterizer || rndCollection == nullptr ){ - LOG_DEBUG << "Loading Fst hits from GEANT with SiRasterizer" << endm; - loadFstHitsFromGEANT( mcTrackMap, hitMap, count ); - } else { - LOG_DEBUG << "Loading Fst hits from StEvent" << endm; - loadFstHitsFromStEvent( mcTrackMap, hitMap, count ); + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from StEvent" << endm; } -} // loadFstHits - -void StFwdTrackMaker::loadFstHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ + return count; +} //loadFstHitsFromStEvent +int StFwdTrackMaker::loadFstHitsFromStRnDHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ + LOG_DEBUG << "Looking for FST hits in StEvent StRnDHit Collection" << endm; + int count = 0; // Get the StEvent handle StEvent *event = (StEvent *)GetDataSet("StEvent"); - if (!event) - return; + if (!event) { + LOG_DEBUG << "No StEvent, cannot load FST FastSim hits from StEvent StRndHitCollection" << endm; + return 0; + } + size_t numFwdHitsPrior = mFwdHitsFst.size(); StRnDHitCollection *rndCollection = event->rndHitCollection(); + if (!rndCollection) return 0; const StSPtrVecRnDHit &hits = rndCollection->hits(); // we will reuse this to hold the cov mat TMatrixDSym hitCov3(3); - - mTreeData.fstN = 0; + for (unsigned int fsthit_index = 0; fsthit_index < hits.size(); fsthit_index++) { StRnDHit *hit = hits[fsthit_index]; - + if ( hit->layer() > 6 ){ // skip sTGC hits here continue; @@ -835,54 +734,64 @@ void StFwdTrackMaker::loadFstHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTra hitCov3(1,0) = covmat[1][0]; hitCov3(1,1) = covmat[1][1]; hitCov3(1,2) = covmat[1][2]; hitCov3(2,0) = covmat[2][0]; hitCov3(2,1) = covmat[2][1]; hitCov3(2,2) = covmat[2][2]; - FwdHit *fhit = new FwdHit(count++, hit->position().x(), hit->position().y(), hit->position().z(), hit->layer(), hit->idTruth(), hitCov3, mcTrackMap[hit->idTruth()]); - size_t index = hit->layer()-4; - if (mGenHistograms && index < 3 ){ - ((TH2*)mHistograms[TString::Format("fsi%luHitMapZ", index).Data()]) -> Fill( hit->position().x(), hit->position().y(), hit->position().z() ); - } - - // Add the hit to the hit map - hitMap[fhit->getSector()].push_back(fhit); + mFwdHitsFst.push_back( + FwdHit( + count++, // id + hit->position().x(), hit->position().y(), hit->position().z(), // position + hit->layer(), // volume id + kFstId, // detid + hit->idTruth(), // mc track id + hitCov3, // covariance matrix + mcTrackMap[hit->idTruth()] // mcTrack + ) + ); mFstHits.push_back( TVector3( hit->position().x(), hit->position().y(), hit->position().z()) ); + } - mTreeData.fstX.push_back( hit->position().x() ); - mTreeData.fstY.push_back( hit->position().y() ); - mTreeData.fstZ.push_back( hit->position().z() ); - mTreeData.fstTrackId.push_back( hit->idTruth() ); - - mTreeData.fstN++; - + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFst.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + } + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from StEvent FastSim" << endm; } + + return count; } //loadFstHitsFromStEvent -void StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ +int StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap ){ + int count = 0; + LOG_DEBUG << "Looking for FST hits in geant struct" << endm; /************************************************************/ // Load FSI Hits from GEANT St_g2t_fts_hit *g2t_fsi_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_fsi_hit"); - if ( !g2t_fsi_hits ) - return; + if ( !g2t_fsi_hits ){ + LOG_DEBUG << "No g2t_fts_hits, cannot load FST hits from GEANT" << endm; + return 0; + } int nfsi = g2t_fsi_hits->GetNRows(); - + size_t numFwdHitsPrior = mFwdHitsFst.size(); // reuse this to store cov mat TMatrixDSym hitCov3(3); - - if ( mGenHistograms ) mHistograms["nHitsFSI"]->Fill(nfsi); - mTreeData.fstN = 0; for (int i = 0; i < nfsi; i++) { g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_fsi_hits->At(i); - + if (0 == git) continue; // geant hit - + int track_id = git->track_p; int volume_id = git->volume_id; // 4, 5, 6 int d = volume_id / 1000; // disk id - + int plane_id = d - 4; float x = git->x[0]; float y = git->x[1]; @@ -890,47 +799,61 @@ void StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrack if (mSiRasterizer->active()) { TVector3 rastered = mSiRasterizer->raster(TVector3(git->x[0], git->x[1], git->x[2])); - - if ( mGenHistograms ) { - mHistograms["fsiHitDeltaR"]->Fill(std::sqrt(x * x + y * y) - rastered.Perp()); - mHistograms["fsiHitDeltaPhi"]->Fill(std::atan2(y, x) - rastered.Phi()); - } + LOG_INFO << TString::Format("Rastered: %f %f %f -> %f %f %f", git->x[0], git->x[1], git->x[2], rastered.X(), rastered.Y(), rastered.Z()) << endm; x = rastered.X(); y = rastered.Y(); + } else { + LOG_INFO << "Using GEANT FST hit positions without rasterization" << endm; } - - if ( mGenHistograms ) mHistograms["fsi_volume_id"]->Fill(d); - - if (plane_id < 3 && plane_id >= 0) { - - if ( mGenHistograms ) { - mHistograms[TString::Format("fsi%dHitMap", plane_id).Data()]->Fill(x, y); - mHistograms[TString::Format("fsi%dHitMapR", plane_id).Data()]->Fill(std::sqrt(x * x + y * y)); - mHistograms[TString::Format("fsi%dHitMapPhi", plane_id).Data()]->Fill(std::atan2(y, x) + TMath::Pi()); - } - } else { + if (plane_id > 3 || plane_id < 0) { continue; } hitCov3 = makeSiCovMat( TVector3( x, y, z ), mFwdConfig ); - FwdHit *hit = new FwdHit(count++, x, y, z, d, track_id, hitCov3, mcTrackMap[track_id]); + mFwdHitsFst.push_back( + FwdHit( + count++, // id + x, y, z, // position + d, // volume id + kFstId, // detid + track_id, // mc track id + hitCov3, // covariance matrix + mcTrackMap[track_id] // mcTrack + ) + ); mFstHits.push_back( TVector3( x, y, z ) ); + } - mTreeData.fstX.push_back( x ); - mTreeData.fstY.push_back( y ); - mTreeData.fstZ.push_back( z ); - mTreeData.fstTrackId.push_back( track_id ); - - mTreeData.fstN++; - + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFst.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); // Add the hit to the hit map - hitMap[hit->getSector()].push_back(hit); + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + + // add to MC track map + if ( hit->getMcTrack() ) + hit->getMcTrack()->addFstHit(hit); } + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from GEANT" << endm; + } + + return count; } // loadFstHitsFromGEANT +/** + * Loads the Monte Carlo (MC) tracks from the GEANT simulation data. + * + * @param mcTrackMap A reference to the MC track map. + * + * @return The number of forward tracks. + * + * @throws None. + */ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ - LOG_DEBUG << "Looking for GEANT sim vertex info" << endm; St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); @@ -938,9 +861,15 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ if ( g2t_vertex != nullptr ) { // Set the MC Vertex for track fitting g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0); - mForwardTracker->setEventVertex( TVector3( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ) ); + TMatrixDSym cov; + cov.ResizeTo(3, 3); + cov(0, 0) = 0.001; + cov(1, 1) = 0.001; + cov(2, 2) = 0.001; + mForwardTracker->setEventVertex( TVector3( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ), cov ); } + // Get geant tracks St_g2t_track *g2t_track = (St_g2t_track *)GetDataSet("geant/g2t_track"); @@ -948,10 +877,7 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ return 0; size_t nShowers = 0; - - mTreeData.mcN = 1; LOG_DEBUG << g2t_track->GetNRows() << " mc tracks in geant/g2t_track " << endm; - if ( mGenHistograms ) mHistograms["nMcTracks"]->Fill(g2t_track->GetNRows()); for (int irow = 0; irow < g2t_track->GetNRows(); irow++) { g2t_track_st *track = (g2t_track_st *)g2t_track->At(irow); @@ -963,65 +889,38 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ float pt2 = track->p[0] * track->p[0] + track->p[1] * track->p[1]; float pt = std::sqrt(pt2); float eta = track->eta; + TVector3 pp( track->p[0], track->p[1], track->p[2] ); float phi = std::atan2(track->p[1], track->p[0]); //track->phi; int q = track->charge; - - if (!mcTrackMap[track_id] ) - mcTrackMap[track_id] = shared_ptr(new McTrack(pt, eta, phi, q, track->start_vertex_p)); - - if (mGenTree && (unsigned)mTreeData.mcN < MAX_TREE_ELEMENTS) { - mTreeData.mcPt.push_back( pt ); - mTreeData.mcEta.push_back( eta ); - mTreeData.mcPhi.push_back( phi ); - mTreeData.mcCharge.push_back( q ); - mTreeData.mcVertexId.push_back( track->start_vertex_p ); - - if (track->is_shower) - nShowers++; - - mTreeData.mcN++; - } else if ( mGenTree ) { - LOG_WARN << "Truncating Mc tracks in TTree output" << endm; - } + // sometimes the track->eta is wrong, pt, phi + if (!mcTrackMap[track_id] ) + mcTrackMap[track_id] = shared_ptr(new McTrack(pp.Pt(), pp.Eta(), pp.Phi(), q, track->start_vertex_p)); } // loop on track (irow) - // now check the Mc tracks against the McEvent filter size_t nForwardTracks = 0; size_t nForwardTracksNoThreshold = 0; for (auto mctm : mcTrackMap ){ if ( mctm.second == nullptr ) continue; - - if ( mGenHistograms ){ - mHistograms[ "McEventPt" ] ->Fill( mctm.second->mPt ); - mHistograms[ "McEventEta" ] ->Fill( mctm.second->mEta ); - mHistograms[ "McEventPhi" ] ->Fill( mctm.second->mPhi ); - } - if ( mctm.second->mEta > 2.5 && mctm.second->mEta < 4.0 ){ - - if ( mGenHistograms ){ - mHistograms[ "McEventFwdPt" ] ->Fill( mctm.second->mPt ); - mHistograms[ "McEventFwdEta" ] ->Fill( mctm.second->mEta ); - mHistograms[ "McEventFwdPhi" ] ->Fill( mctm.second->mPhi ); - } - nForwardTracksNoThreshold++; if ( mctm.second->mPt > 0.05 ) nForwardTracks++; } } // loop on mcTrackMap - - if ( mGenHistograms ) { - mHistograms[ "nMcTracksFwd" ]->Fill( nForwardTracks ); - mHistograms[ "nMcTracksFwdNoThreshold" ]->Fill( nForwardTracksNoThreshold ); - } - - return nForwardTracks; } // loadMcTracks +/** + * Load FCS data from StEvent for ECAL/HCAL clusters and Preshower hits (EPD). + * + * @param None + * + * @return None + * + * @throws None + */ void StFwdTrackMaker::loadFcs( ) { StEvent *stEvent = static_cast(GetInputDS("StEvent")); StFcsDb* fcsDb=static_cast(GetDataSet("fcsDb")); @@ -1035,8 +934,6 @@ void StFwdTrackMaker::loadFcs( ) { StEpdGeom epdgeo; - mTreeData.fcsN = 0; - // LOAD ECAL / HCAL CLUSTERS for ( int idet = 0; idet < 4; idet++ ){ StSPtrVecFcsCluster& clusters = fcsCol->clusters(idet); @@ -1046,13 +943,8 @@ void StFwdTrackMaker::loadFcs( ) { StThreeVectorD xyz = fcsDb->getStarXYZfromColumnRow(clu->detectorId(),clu->x(),clu->y()); mFcsClusters.push_back( TVector3( xyz.x(), xyz.y(), xyz.z() - 2 ) ); mFcsClusterEnergy.push_back( clu->energy() ); - - mTreeData.fcsX.push_back( xyz.x() ); - mTreeData.fcsY.push_back( xyz.y() ); - mTreeData.fcsZ.push_back( xyz.z() - 2 ); - mTreeData.fcsDet.push_back( idet ); - } - } + } // i + } // idet // LOAD PRESHOWER HITS (EPD) for ( int det = 4; det < 6; det ++ ) { @@ -1073,37 +965,142 @@ void StFwdTrackMaker::loadFcs( ) { double x0 = (x[0] + x[1] + x[2] + x[3]) / 4.0; double y0 = (y[0] + y[1] + y[2] + y[3]) / 4.0; mFcsPreHits.push_back( TVector3( x0, y0, zepd ) ); + } // if det + } // for i + } // for det +} // loadFcs - mTreeData.fcsX.push_back( x0 ); - mTreeData.fcsY.push_back( y0 ); - mTreeData.fcsZ.push_back( zepd ); - mTreeData.fcsDet.push_back( det ); +TVector3 StFwdTrackMaker::GetEventPrimaryVertex(){ + if ( mFwdVertexSource == kFwdVertexSourceNone ){ + // Note - maybe we will add beamline or assume some default + return TVector3(0, 0, 0); // the default vertex, but in general it should not be used + } - } - } + if ( mFwdVertexSource != kFwdVertexSourceUnknown ){ + return mEventVertex; } -} // loadFcs + mEventVertexCov.ResizeTo(3, 3); + mEventVertexCov.Zero(); + double sig2 = 1; + mEventVertexCov(0, 0) = sig2; // default resolution + mEventVertexCov(1, 1) = sig2; + mEventVertexCov(2, 2) = sig2; + // if something is found it will overwrite this, if not + // it will indicate that we have searched and found nothing + mFwdVertexSource = kFwdVertexSourceNone; + + /***************************************************** + * Add Primary Vertex to the track + */ + St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); + if ( g2t_vertex != nullptr ) { + // Set the MC Vertex for track fitting + g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0); + + mEventVertexCov.ResizeTo(3, 3); + const double sigXY = 0.1; + const double sigZ = 10.0; + mEventVertexCov(0, 0) = pow(sigXY,2); + mEventVertexCov(1, 1) = pow(sigXY,2); + mEventVertexCov(2, 2) = pow(sigZ, 2); + auto rhc = TVectorD( 3 ); + rhc[0] = vert->ge_x[0]; + rhc[1] = vert->ge_x[1]; + rhc[2] = vert->ge_x[2]; + mEventVertex.SetXYZ( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ); + mFwdVertexSource = kFwdVertexSourceMc; + return mEventVertex; + } + + // or try the McEvent + StMcEvent *stMcEvent = static_cast(GetInputDS("StMcEvent")); + if (stMcEvent) { + LOG_INFO << "Setting Event Vertex from StMcEvent: " << stMcEvent << endm; + StThreeVectorF vertex = stMcEvent->primaryVertex()->position(); + mEventVertex.SetXYZ( vertex.x(), vertex.y(), vertex.z() ); + mFwdVertexSource = kFwdVertexSourceMc; + LOG_INFO << "FWD Tracking on event with MC Primary Vertex: " << mEventVertex.X() << ", " << mEventVertex.Y() << ", " << mEventVertex.Z() << endm; + + mEventVertexCov(0, 0) = 0.1 * 0.1; // default resolution + mEventVertexCov(1, 1) = 0.1 * 0.1; // default resolution + mEventVertexCov(2, 2) = 0.1 * 0.1; // default resolution + return mEventVertex; + } else { + LOG_DEBUG << "No available Mc Primary Vertex" << endm; + } + + // MuDst only for now + int count = 0; + StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); + if(mMuDstMaker && mMuDstMaker->muDst() && mMuDstMaker->muDst()->primaryVertex() ) { + auto muPV = mMuDstMaker->muDst()->primaryVertex(); + mEventVertex.SetX(muPV->position().x()); + mEventVertex.SetY(muPV->position().y()); + mEventVertex.SetZ(muPV->position().z()); + mFwdVertexSource = kFwdVertexSourceTpc; + return mEventVertex; + } else { + LOG_DEBUG << "FWD Tracking on event without available Mu Primary Vertex" << endm; + StEvent *stEvent = static_cast(GetInputDS("StEvent")); + if (!stEvent) return mEventVertex; + StBTofCollection *btofC = stEvent->btofCollection(); + if (!btofC) { + LOG_WARN << "Cannot get BTOF collections, Cannot use VPD vertex" << endm; + return mEventVertex; + } + + StBTofHeader * btofHeader = btofC->tofHeader(); + if (!btofHeader){ + LOG_WARN << "Cannot get BTOF Header, Cannot use VPD vertex" << endm; + return mEventVertex; + } + + int nEast = btofHeader->numberOfVpdHits( east ); + int nWest = btofHeader->numberOfVpdHits( west ); + int nTof = btofC->tofHits().size(); + + if ( btofHeader->vpdVz() && fabs(btofHeader->vpdVz()) < 100 ){ + // default event vertex + LOG_DEBUG << "FWD Tracking on event using VPD z vertex: (, 0, 0, " << btofHeader->vpdVz() << " )" << endm; + mFwdVertexSource = kFwdVertexSourceVpd; + mEventVertex.SetXYZ( 0, 0, btofHeader->vpdVz() ); + return mEventVertex; + } + } + return mEventVertex; +} //________________________________________________________________________ int StFwdTrackMaker::Make() { // START time for measuring tracking long long itStart = FwdTrackerUtils::nowNanoSecond(); - // Access forward Tracker maps + StEvent *stEvent = static_cast(GetInputDS("StEvent")); + if (!stEvent) return kStOk; + + /**********************************************************************/ + // Access forward track and hit maps FwdDataSource::McTrackMap_t &mcTrackMap = mForwardData->getMcTracks(); FwdDataSource::HitMap_t &hitMap = mForwardData->getFttHits(); FwdDataSource::HitMap_t &fsiHitMap = mForwardData->getFstHits(); - - // clear vectors for visualization OBJ hits - mFttHits.clear(); - mFstHits.clear(); - mFcsPreHits.clear(); - mFcsClusters.clear(); - mFwdTracks.clear(); - - // default event vertex - mForwardTracker->setEventVertex( TVector3( 0, 0, 0 ) ); + + /**********************************************************************/ + // get the primary vertex for use with FWD tracking + mFwdVertexSource = StFwdTrackMaker::kFwdVertexSourceUnknown; + GetEventPrimaryVertex(); + LOG_DEBUG << "FWD Vertex Source: " << mFwdVertexSource << endm; + if ( mFwdVertexSource == kFwdVertexSourceNone ){ + // TODO: add clean support for beamline constraints + setIncludePrimaryVertexInFit( false ); + } else if ( mFwdVertexSource == kFwdVertexSourceUnknown ){ + LOG_WARN << "FwdVertexSource=Unknown even after looking, shouldnt be possible. Not using primary vertex in forward tracking" << endm; + // this should not be possible + setIncludePrimaryVertexInFit( false ); + } else { + LOG_DEBUG << "Setting FWD event vertex to: " << TString::Format("mEventVertex=(%0.3f+/-%0.3f, %0.3f+/-%0.3f, %0.3f+/-%0.3f)", mEventVertex.X(), sqrt(mEventVertexCov(0, 0)), mEventVertex.Y(), sqrt(mEventVertexCov(1, 1)), mEventVertex.Z(), sqrt(mEventVertexCov(2, 2)) ) << endm; + mForwardTracker->setEventVertex( mEventVertex, mEventVertexCov ); + } /**********************************************************************/ // Load MC tracks @@ -1116,18 +1113,18 @@ int StFwdTrackMaker::Make() { LOG_DEBUG << "We have " << nForwardTracks << " forward MC tracks" << endm; /**********************************************************************/ - // Load sTGC + // Load sTGC LOG_DEBUG << ">>StFwdTrackMaker::loadFttHits" << endm; if ( IAttr("useFtt") ) { loadFttHits( mcTrackMap, hitMap ); } - /**********************************************************************/ // Load FST - LOG_DEBUG << ">>StFwdTrackMaker::loadFstHits" << endm; if ( IAttr("useFst") ) { - loadFstHits( mcTrackMap, fsiHitMap ); + LOG_DEBUG << ">>StFwdTrackMaker::loadFstHits" << endm; + int fstCount = loadFstHits( mcTrackMap, fsiHitMap ); + LOG_DEBUG << "Loaded " << fstCount << " FST hits" << endm; } /**********************************************************************/ @@ -1137,104 +1134,84 @@ int StFwdTrackMaker::Make() { loadFcs(); } + /**********************************************************************/ + // Print out the MC tracks and their hit counts + for ( auto kv : mcTrackMap ){ + if ( kv.second == nullptr ) continue; + LOG_DEBUG << "MC Track: id=" << kv.first << ", nFTT=" << kv.second->mFttHits.size() << ", nFST=" << kv.second->mFstHits.size() << endm; + } + /**********************************************************************/ // Run Track finding + fitting LOG_DEBUG << ">>START Event Forward Tracking" << endm; - mForwardTracker->doEvent(); + LOG_INFO << "\tFinding FWD Track Seeds" << endm; + mForwardTracker->findTrackSeeds(); + LOG_INFO << "\tFitting FWD Track Seeds" << endm; + // in principle we could filter the track seeds further if we wanted + mForwardTracker->doTrackFitting( mForwardTracker->getTrackSeeds() ); LOG_DEBUG << "< getRecoTracks().size() << " GenFit Tracks" << endm; - + LOG_INFO << "< getTrackSeeds().size() << " Track Seeds" << endm; + LOG_INFO << "< getTrackResults().size() << " GenFit Tracks" << endm; + /**********************************************************************/ - FitVertex(); - - StEvent *stEvent = static_cast(GetInputDS("StEvent")); /**********************************************************************/ - // Run Track finding + fitting - - const auto &genfitTracks = mForwardTracker -> globalTracks(); - if ( mVisualize /* && genfitTracks.size() > 0 && genfitTracks.size() < 200*/ ) { - const auto &seed_tracks = mForwardTracker -> getRecoTracks(); + // Output track visualization if configured to do so + if ( mVisualize ){ + std::vector genfitTracks; + for ( auto gtr : mForwardTracker->getTrackResults() ) { + if ( gtr.mIsFitConvergedFully == false ) continue; + genfitTracks.push_back( gtr.mTrack.get() ); + } - ObjExporter woe; - woe.output( - TString::Format( "ev%lu", eventIndex ).Data(), - stEvent, - seed_tracks, genfitTracks, mRaveVertices, - mFttHits, mFstHits, mFcsPreHits, mFcsClusters, mFcsClusterEnergy ); - eventIndex++; - LOG_DEBUG << "Done Writing OBJ " << endm; - } else if (mVisualize && genfitTracks.size() == 0) { - LOG_DEBUG << "Skipping visualization, no FWD tracks" << endm; - } else if (mVisualize && genfitTracks.size() >= 20) { - LOG_DEBUG << "Skipping visualization, too many FWD tracks" << endm; + if ( mVisualize && genfitTracks.size() > 0 && genfitTracks.size() < 400 && eventIndex < 50 ) { + const auto &seed_tracks = mForwardTracker -> getTrackSeeds(); + + ObjExporter woe; + woe.output( + TString::Format( "ev%lu", eventIndex ).Data(), + stEvent, + seed_tracks, genfitTracks, mRaveVertices, + mFttHits, mFstHits, mFcsPreHits, mFcsClusters, mFcsClusterEnergy ); + eventIndex++; + LOG_DEBUG << "Done Writing OBJ " << endm; + } else if (mVisualize && genfitTracks.size() == 0) { + LOG_DEBUG << "Skipping visualization, no FWD tracks" << endm; + } else if (mVisualize && genfitTracks.size() >= 400) { + LOG_DEBUG << "Skipping visualization, too many FWD tracks" << endm; + } } - // Fill Track Deltas in ttree for helpful alignment info - FillTrackDeltas(); - - LOG_INFO << "Forward tracking on this event took " << (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6 << " ms" << endm; - - if ( true && IAttr("fillEvent") ) { - + LOG_DEBUG << "Forward tracking on this event took " << (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6 << " ms" << endm; + if ( IAttr("fillEvent") ) { if (!stEvent) { LOG_WARN << "No StEvent found. Forward tracks will not be saved" << endm; return kStWarn; } - FillEvent(); } // IAttr FillEvent - LOG_DEBUG << "Filling fwd Tree for event: " << GetIventNumber() << endm; - FillTTree(); return kStOK; } // Make - +/** + * Creates a StFwdTrack object from a GenfitTrackResult. + * + * @param gtr The GenfitTrackResult object containing the track information. + * @param indexTrack The index of the track. + * + * @return A pointer to the created StFwdTrack object, or nullptr if the GenfitTrackResult is nullptr. + * + * @throws None. + */ StFwdTrack * StFwdTrackMaker::makeStFwdTrack( GenfitTrackResult >r, size_t indexTrack ){ LOG_DEBUG << "StFwdTrackMaker::makeStFwdTrack()" << endm; - StFwdTrack *fwdTrack = new StFwdTrack( ); - - auto track = gtr.track; - // if FST refit is available save that - if ( gtr.nFST > 0 && gtr.fstTrack != nullptr){ - LOG_DEBUG << "\tSave FST refit track since we have FST points" << endm; - track = gtr.fstTrack; - } else if (gtr.nFST > 0 && gtr.fstTrack == nullptr) { - LOG_WARN << "\tFST refit failed even though we have " << gtr.nFST << " FST points" << endm; - } - - // Fit failed beyond use - if ( track == nullptr ){ - LOG_DEBUG << "Track is nullptr, not saving StFwdTrack" << endm; - return nullptr; - } - - auto fitStatus = track->getFitStatus(); - if ( !fitStatus ) - return nullptr; - - // Fill charge and quality info - fwdTrack->setDidFitConverge( fitStatus->isFitConverged() ); - fwdTrack->setDidFitConvergeFully( fitStatus->isFitConvergedFully() ); - fwdTrack->setNumberOfFailedPoints( fitStatus->getNFailedPoints() ); - - fwdTrack->setNumberOfFitPoints( track->getNumPoints() ); - fwdTrack->setChi2( fitStatus->getChi2() ); - fwdTrack->setNDF( fitStatus->getNdf() ); - fwdTrack->setPval( fitStatus->getPVal() ); - - auto cr = track->getCardinalRep(); - // charge at first point - fwdTrack->setCharge( gtr.charge ); - - TVector3 p = cr->getMom( track->getFittedState( 0, cr )); - fwdTrack->setPrimaryMomentum( StThreeVectorD( gtr.momentum.X(), gtr.momentum.Y(), gtr.momentum.Z() ) ); - LOG_DEBUG << "Making StFwdTrack with " << TString::Format( "p=(%f, %f, %f)", fwdTrack->momentum().x(), fwdTrack->momentum().y(), fwdTrack->momentum().z() ) << endm; + StFwdTrack *fwdTrack = new StFwdTrack( ); + /*******************************************************************************/ + // store the seed points for the track int nSeedPoints = 0; - // store the seed points from FTT - for ( auto s : gtr.trackSeed ){ + for ( auto s : gtr.mSeed ){ FwdHit * fh = static_cast( s ); if (!fh) continue; float cov[9]; @@ -1242,101 +1219,112 @@ StFwdTrack * StFwdTrackMaker::makeStFwdTrack( GenfitTrackResult >r, size_t ind cov[1] = fh->_covmat(0,1); cov[4] = fh->_covmat(1,1); cov[7] = fh->_covmat(2,1); cov[2] = fh->_covmat(0,2); cov[5] = fh->_covmat(1,2); cov[8] = fh->_covmat(2,2); - StFwdTrackSeedPoint p( StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), fh->getSector(), fh->getTrackId(), cov ); - fwdTrack->mFTTPoints.push_back( p ); - nSeedPoints++; - } - - for ( auto s : gtr.fstSeed ){ - FwdHit * fh = static_cast( s ); - if (!fh) continue; - float cov[9]; - cov[0] = fh->_covmat(0,0); cov[3] = fh->_covmat(1,0); cov[6] = fh->_covmat(2,0); - cov[1] = fh->_covmat(0,1); cov[4] = fh->_covmat(1,1); cov[7] = fh->_covmat(2,1); - cov[2] = fh->_covmat(0,2); cov[5] = fh->_covmat(1,2); cov[8] = fh->_covmat(2,2); + StFwdTrackSeedPoint p( + StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), + fh->_detid * 10 + fh->getSector(), // 10 * detid + sector + fh->getTrackId(), + cov + ); + if ( fh->isFst() ) + fwdTrack->mFSTPoints.push_back( p ); + else if ( fh->isFtt() ) + fwdTrack->mFTTPoints.push_back( p ); - StFwdTrackSeedPoint p( StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), fh->getSector(), fh->getTrackId(), cov ); - fwdTrack->mFSTPoints.push_back( p ); nSeedPoints++; } // set total number of seed points fwdTrack->setNumberOfSeedPoints( nSeedPoints ); + int idt = 0; + double qual = 0; + idt = MCTruthUtils::dominantContribution(gtr.mSeed, qual); + fwdTrack->setMc( idt, qual*100 ); // QAtruth stored as UChar_t + LOG_DEBUG << "Dominant contribution: " << idt << " with quality " << qual << endm; - // compute projections to z-planes of various detectors - vector zPlanes = { - 0, // PV TODO, update with event vertex? - 151.750000, 165.248001, 178.781006, // FST - 280.904999, 303.704987, 326.605011, 349.404999, // FTT - 375.0, // EPD - 715.0, //ECAL - 807.0 // HCAL - }; - - // Note: as discussed, after verification storage of the projections - // @ the FST and FTT may no longer be needed, not saved in e.g. MuDst + // Fit failed beyond use + if ( gtr.mTrack == nullptr ){ + gtr.Clear(); + LOG_DEBUG << "GenfitTrack is nullptr, making StFwdTrack with seed info only" << endm; + return fwdTrack; + } + // Fill charge and quality info + fwdTrack->setDidFitConverge( gtr.mStatus->isFitConverged() ); + fwdTrack->setDidFitConvergeFully( gtr.mStatus->isFitConvergedFully() ); + fwdTrack->setNumberOfFailedPoints( gtr.mStatus->getNFailedPoints() ); - // this should always be the case, but being careful - if (gGeoManager) { - FwdGeomUtils fwdGeoUtils( gGeoManager ); - - // get the z-locations from geometry model and fallback to the defaults - auto fstZ = fwdGeoUtils.fstZ( {151.750000, 165.248001, 178.781006} ); - auto fttZ = fwdGeoUtils.fttZ( {280.904999, 303.704987, 326.605011, 349.404999} ); + fwdTrack->setNumberOfFitPoints( gtr.mTrack->getNumPoints() ); + fwdTrack->setChi2( gtr.mStatus->getChi2() ); + fwdTrack->setNDF( gtr.mStatus->getNdf() ); + fwdTrack->setPval( gtr.mStatus->getPVal() ); + + // charge at first point + fwdTrack->setCharge( gtr.mCharge ); + fwdTrack->setDCA( gtr.mDCA.X(), gtr.mDCA.Y(), gtr.mDCA.Z() ); + + TVector3 p = gtr.mMomentum;//cr->getMom( gtr.mTrack->getFittedState( 0, cr )); + fwdTrack->setPrimaryMomentum( StThreeVectorD( gtr.mMomentum.X(), gtr.mMomentum.Y(), gtr.mMomentum.Z() ) ); + + if ( gtr.isPrimary ){ + fwdTrack->setVtxIndex( 0 ); + } else { + fwdTrack->setVtxIndex( UCHAR_MAX ); + } + + /*******************************************************************************/ + // if the track is not (at least partially) converged, do not try to project it + if ( !gtr.mStatus->isFitConvergedPartially() ){ + gtr.Clear(); + return fwdTrack; + } - // copy new values into the zPlanes vector - std::copy( fstZ.begin(), fstZ.end(), zPlanes.begin()+1 ); - std::copy( fttZ.begin(), fttZ.end(), zPlanes.begin()+4 ); - } - - // Match these to the z-planes above - const int FST = kFstId; - const int FTT = kFttId; - vector detMap = { - kTpcId, - FST, FST, FST, - FTT, FTT, FTT, FTT, - kFcsPresId, - kFcsWcalId, - kFcsHcalId + /*******************************************************************************/ + // compute projections to z-planes of various detectors + // TODO: update FCS to use correct z + angle + map mapDetectorToZPlane = { + { kTpcId, 0.0 }, + { kFstId, mFstZFromGeom[0] }, + { kFstId, mFstZFromGeom[1] }, + { kFstId, mFstZFromGeom[2] }, + { kFttId, mFttZFromGeom[0] }, + { kFttId, mFttZFromGeom[1] }, + { kFttId, mFttZFromGeom[2] }, + { kFttId, mFttZFromGeom[3] }, + { kFcsPresId, 375.0 }, + { kFcsWcalId, 715.0 }, + { kFcsHcalId, 807.0 } }; size_t zIndex = 0; - int detIndex = 0; - for ( float z : zPlanes ){ - detIndex = detMap[ zIndex]; - // LOG_DEBUG << "Calculating Projection for detId=" << detIndex << " @ z=" << z << endm; - TVector3 mom(0, 0, 0); - float cov[9]; - - TVector3 tv3(0, 0, 0); - if ( detIndex != kFcsHcalId ){ - tv3 = ObjExporter::trackPosition( track, z, cov, mom ); + TVector3 mom(0, 0, 0); + float cov[9]; + TVector3 tv3(0, 0, 0); + for ( auto zp : mapDetectorToZPlane ){ + int detIndex = zp.first; + float z = zp.second; + tv3.SetXYZ(0, 0, 0); + if ( detIndex != kFcsHcalId && detIndex != kFcsWcalId ){ + tv3 = ObjExporter::trackPosition( gtr.mTrack.get(), z, cov, mom ); } else { // use a straight line projection to HCAL since GenFit cannot handle long projections - tv3 = ObjExporter::projectAsStraightLine( track, 575.0, 625.0, z, cov, mom ); + tv3 = ObjExporter::projectAsStraightLine( gtr.mTrack.get(), 575.0, 625.0, z, cov, mom ); } fwdTrack->mProjections.push_back( StFwdTrackProjection( detIndex, StThreeVectorF( tv3.X(), tv3.Y(), tv3.Z() ), StThreeVectorF( mom.X(), mom.Y(), mom.Z() ), cov) ); - - // // Add Proj info to TTree - mTreeData.tprojX.push_back( tv3.X() ); - mTreeData.tprojY.push_back( tv3.Y() ); - mTreeData.tprojZ.push_back( tv3.Z() ); - mTreeData.tprojIdD.push_back( detIndex ); - mTreeData.tprojIdT.push_back( indexTrack ); - zIndex++; } + /*******************************************************************************/ - return fwdTrack; + /*******************************************************************************/ + // clear the GenfitTrackResult + gtr.Clear(); + + // return the StFwdTrack we made + return fwdTrack; } void StFwdTrackMaker::FillEvent() { - LOG_DEBUG << "StFwdTrackMaker::FillEvent()" << endm; - // Now fill StEvent StEvent *stEvent = static_cast(GetInputDS("StEvent")); - - // FillEvent(); + if (!stEvent) + return; StFwdTrackCollection * ftc = stEvent->fwdTrackCollection(); if ( !ftc ){ LOG_INFO << "Creating the StFwdTrackCollection" << endm; @@ -1344,57 +1332,34 @@ void StFwdTrackMaker::FillEvent() { stEvent->setFwdTrackCollection( ftc ); } - mTreeData.tprojN = 0; - mTreeData.tprojX.clear(); - mTreeData.tprojY.clear(); - mTreeData.tprojZ.clear(); - mTreeData.tprojIdD.clear(); - mTreeData.tprojIdT.clear(); - size_t indexTrack = 0; + size_t indexTrack = 0; for ( auto gtr : mForwardTracker->getTrackResults() ) { - StFwdTrack* fwdTrack = makeStFwdTrack( gtr, indexTrack ); - if (nullptr == fwdTrack) - continue; - ftc->addTrack( fwdTrack ); + StFwdTrack* fwdTrack = makeStFwdTrack( gtr, indexTrack ); + indexTrack++; + if (nullptr == fwdTrack) + continue; + ftc->addTrack( fwdTrack ); } + LOG_INFO << "StFwdTrackCollection has " << ftc->numberOfTracks() << " tracks now" << endm; - mTreeData.tprojN = mTreeData.tprojX.size(); - LOG_DEBUG << "StFwdTrackCollection has " << ftc->numberOfTracks() << " tracks now" << endm; - ProcessFwdTracks(); -} - -void StFwdTrackMaker::FillTrackDeltas(){ - LOG_DEBUG << "Filling Track Deltas for Alignment" << endm; - const auto &fittedTracks = mForwardTracker -> getTrackResults(); - - for ( size_t i = 0; i < fittedTracks.size(); i++ ){ - auto st = fittedTracks[i].trackSeed; - auto gt = fittedTracks[i].track; - - if (fittedTracks[i].isFitConvergedFully == false){ - LOG_DEBUG << "Skipping track, failed fit" << endm; - continue; - } - - for ( KiTrack::IHit * hit : st ){ - TVector3 htv3(hit->getX(), hit->getY(), hit->getZ()); - - auto ttv3 = ObjExporter::trackPosition( gt, htv3.Z() ); - - mTreeData.thdX.push_back( (ttv3.X() - htv3.X()) ); - mTreeData.thdY.push_back( (ttv3.Y() - htv3.Y()) ); - mTreeData.thaX.push_back( htv3.X() ); - mTreeData.thaY.push_back( htv3.Y() ); - mTreeData.thaZ.push_back( htv3.Z() ); - mTreeData.thdN++; - } + // Pico Dst requires a primary vertex, + // if we have a PicoDst maker in the chain, we need to add a primary vertex + // when one does not exist to get a "FWD" picoDst + auto mk = GetMaker("PicoDst"); + if ( mk && stEvent->numberOfPrimaryVertices() == 0 ){ + LOG_INFO << "Adding a primary vertex to StEvent since PicoDst maker was found in chain, but no vertices found" << endm; + stEvent->addPrimaryVertex( new StPrimaryVertex() ); + LOG_INFO << "StPrimaryVertex::numberOfPrimaryVertices = " << stEvent->numberOfPrimaryVertices() << endm; } -} //FillTrackDeltas + + // ProcessFwdTracks(); +} void StFwdTrackMaker::FitVertex(){ - const auto &genfitTracks = mForwardTracker -> globalTracks(); + vector genfitTracks; + const auto &trackResults = mForwardTracker -> getTrackResults(); if ( genfitTracks.size() >= 2 ){ genfit::GFRaveVertexFactory gfrvf; @@ -1404,281 +1369,34 @@ void StFwdTrackMaker::FitVertex(){ bscm(1, 1) = bssXY*bssXY; bscm(2, 2) = 50.5 * 50.5; gfrvf.setBeamspot( TVector3( 0, 0, 0 ), bscm ); - // std::vector< genfit::GFRaveVertex * > vertices; - const auto &genfitTracks = mForwardTracker -> globalTracks(); + mRaveVertices.clear(); gfrvf.findVertices( &mRaveVertices, genfitTracks, false ); - + LOG_DEBUG << "mRaveVertices.size() = " << mRaveVertices.size() << endm; - for ( auto vert : mRaveVertices ){ LOG_DEBUG << TString::Format( "RAVE vertex @(%f, %f, %f)\n\n", vert->getPos().X(), vert->getPos().Y(), vert->getPos().Z() ) << endm; } } -} - -void StFwdTrackMaker::FillTTree(){ - - St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); - if (mGenTree) { - - // VERTICES - if ( g2t_vertex ){ - mTreeData.vmcN = g2t_vertex->GetNRows(); - if ( (unsigned)mTreeData.vmcN >= MAX_TREE_ELEMENTS ) mTreeData.vmcN = MAX_TREE_ELEMENTS; - LOG_INFO << "Saving " << mTreeData.vmcN << " vertices in TTree" << endm; - for ( int i = 0; i < mTreeData.vmcN; i++ ){ - g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(i); - mTreeData.vmcX.push_back( vert->ge_x[0] ); - mTreeData.vmcY.push_back( vert->ge_x[1] ); - mTreeData.vmcZ.push_back( vert->ge_x[2] ); - } - } - - // RAVE RECO VERTICES - mTreeData.vrcN = mRaveVertices.size(); - if ( (unsigned)mTreeData.vrcN >= MAX_TREE_ELEMENTS ) mTreeData.vrcN = MAX_TREE_ELEMENTS; - LOG_INFO << "Saving " << mTreeData.vrcN << " RAVE vertices in TTree" << endm; - for ( int i = 0; i < mTreeData.vrcN; i++ ) { - auto vert = mRaveVertices[i]; - mTreeData.vrcX.push_back( vert->getPos().X() ); - mTreeData.vrcY.push_back( vert->getPos().Y() ); - mTreeData.vrcZ.push_back( vert->getPos().Z() ); - } - - - - - if (mForwardTracker->getSaveCriteriaValues() && mTreeData.saveCrit ) { - for (auto crit : mForwardTracker->getTwoHitCriteria()) { - string name = crit->getName(); - - // special, save all hit info for this one - - - if ( name == "Crit2_BDT" ){ - mTreeData.Crits["Crit2_BDT_DeltaPhi"].clear(); - mTreeData.Crits["Crit2_BDT_DeltaRho"].clear(); - mTreeData.Crits["Crit2_BDT_RZRatio"].clear(); - mTreeData.Crits["Crit2_BDT_StraightTrackRatio"].clear(); - - for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { - mTreeData.Crits["Crit2_BDT_DeltaPhi"].push_back( kv["Crit2_BDT_DeltaPhi"] ); - mTreeData.Crits["Crit2_BDT_DeltaRho"].push_back( kv["Crit2_BDT_DeltaRho"] ); - mTreeData.Crits["Crit2_BDT_RZRatio"].push_back( kv["Crit2_BDT_RZRatio"] ); - mTreeData.Crits["Crit2_BDT_StraightTrackRatio"].push_back( kv["Crit2_BDT_StraightTrackRatio"] ); - } - - } - - if ( name == "Crit2_RZRatio" ){ - LOG_INFO << "allValues.size() = " << mForwardTracker->getCriteriaAllValues(name).size() << " == " << mForwardTracker->getCriteriaTrackIds(name).size() << endm; - assert( mForwardTracker->getCriteriaAllValues(name).size() == mForwardTracker->getCriteriaTrackIds(name).size() && " Crit lengths must be equal" ); - mTreeData.Crits["Crit2_RZRatio_x1"].clear(); - mTreeData.Crits["Crit2_RZRatio_y1"].clear(); - mTreeData.Crits["Crit2_RZRatio_z1"].clear(); - mTreeData.Crits["Crit2_RZRatio_x2"].clear(); - mTreeData.Crits["Crit2_RZRatio_y2"].clear(); - mTreeData.Crits["Crit2_RZRatio_z2"].clear(); - - mTreeData.CritTrackIds["Crit2_RZRatio_h1"].clear(); - mTreeData.CritTrackIds["Crit2_RZRatio_h2"].clear(); - mTreeData.CritTrackIds["Crit2_RZRatio_h3"].clear(); - - - for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { - mTreeData.Crits["Crit2_RZRatio_x1"].push_back( kv["Crit2_RZRatio_x1"] ); - mTreeData.Crits["Crit2_RZRatio_y1"].push_back( kv["Crit2_RZRatio_y1"] ); - mTreeData.Crits["Crit2_RZRatio_z1"].push_back( kv["Crit2_RZRatio_z1"] ); - - mTreeData.Crits["Crit2_RZRatio_x2"].push_back( kv["Crit2_RZRatio_x2"] ); - mTreeData.Crits["Crit2_RZRatio_y2"].push_back( kv["Crit2_RZRatio_y2"] ); - mTreeData.Crits["Crit2_RZRatio_z2"].push_back( kv["Crit2_RZRatio_z2"] ); - - mTreeData.CritTrackIds["Crit2_RZRatio_h1"].push_back( kv["Crit2_RZRatio_h1"] ); - mTreeData.CritTrackIds["Crit2_RZRatio_h2"].push_back( kv["Crit2_RZRatio_h2"] ); - mTreeData.CritTrackIds["Crit2_RZRatio_h3"].push_back( -1 ); - } - } - - - LOG_DEBUG << "Saving Criteria values from " << name << " in TTree" << endm; - mTreeData.Crits[name].clear(); - mTreeData.CritTrackIds[name].clear(); - // copy by value so ROOT doesnt get lost (uses pointer to vector) - for (float v : mForwardTracker->getCriteriaValues(name)) { - mTreeData.Crits[name].push_back(v); - } - for (int v : mForwardTracker->getCriteriaTrackIds(name)) { - mTreeData.CritTrackIds[name].push_back(v); - } - } - - // three hit criteria - for (auto crit : mForwardTracker->getThreeHitCriteria()) { - string name = crit->getName(); - - // special, save all hit info for this one - if ( name == "Crit2_RZRatio" ){ - LOG_INFO << "allValues.size() = " << mForwardTracker->getCriteriaAllValues(name).size() << " == " << mForwardTracker->getCriteriaTrackIds(name).size() << endm; - assert( mForwardTracker->getCriteriaAllValues(name).size() == mForwardTracker->getCriteriaTrackIds(name).size() && " Crit lengths must be equal" ); - - mTreeData.CritTrackIds["Crit2_RZRatio_h1"].clear(); - mTreeData.CritTrackIds["Crit2_RZRatio_h2"].clear(); - mTreeData.CritTrackIds["Crit2_RZRatio_h3"].clear(); - - for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { - mTreeData.CritTrackIds["Crit2_RZRatio_h1"].push_back( kv["Crit2_RZRatio_h1"] ); - mTreeData.CritTrackIds["Crit2_RZRatio_h2"].push_back( kv["Crit2_RZRatio_h2"] ); - mTreeData.CritTrackIds["Crit2_RZRatio_h3"].push_back( kv["Crit2_RZRatio_h3"] ); - } - } - - - LOG_DEBUG << "Saving Criteria values from " << name << " in TTree" << endm; - mTreeData.Crits[name].clear(); - mTreeData.CritTrackIds[name].clear(); - // copy by value so ROOT doesnt get lost (uses pointer to vector) - for (float v : mForwardTracker->getCriteriaValues(name)) { - mTreeData.Crits[name].push_back(v); - } - for (int v : mForwardTracker->getCriteriaTrackIds(name)) { - mTreeData.CritTrackIds[name].push_back(v); - } - } - - // clear them - mForwardTracker->clearSavedCriteriaValues(); - } - - // SAVE RECO tracks - - mTreeData.rcN = 0; - const auto &fittedTracks = mForwardTracker -> getTrackResults(); - - LOG_INFO << "There are " << fittedTracks.size() << " seed tracks to save" << endm; - size_t maxToSave = fittedTracks.size(); - if (maxToSave >= 200) { - maxToSave = 0; - LOG_INFO << "More than 200 tracks , not saving unfit tracks" << endm; - } - - for ( size_t i = 0; i < maxToSave; i++ ){ - if ( i >= MAX_TREE_ELEMENTS ){ - LOG_WARN << "Truncating Reco tracks in TTree output" << endm; - break; - } - - int idt = 0; - double qual = 0; - idt = MCTruthUtils::dominantContribution(fittedTracks[i].trackSeed, qual); - - if ( fittedTracks[i].track == nullptr || fittedTracks[i].trackRep == nullptr ) { - LOG_INFO << "Skip saving null track" << endm; - continue; - } - - if ( fittedTracks[i].isFitConverged == false ){ - LOG_INFO << "Skip saving track where fit did not converge" << endm; - continue; - } - - - mTreeData.rcQuality.push_back( qual ); - mTreeData.rcTrackId.push_back( idt ); - - mTreeData.rcCharge.push_back( fittedTracks[i].charge ); - mTreeData.rcPt.push_back( fittedTracks[i].momentum.Pt() ); - mTreeData.rcEta.push_back( fittedTracks[i].momentum.Eta() ); - mTreeData.rcPhi.push_back( fittedTracks[i].momentum.Phi() ); - - mTreeData.rcNumPV.push_back( fittedTracks[i].nPV ); - mTreeData.rcNumFTT.push_back( fittedTracks[i].nFTT ); - mTreeData.rcNumFST.push_back( fittedTracks[i].nFST ); - - mTreeData.rcN ++; - } - LOG_INFO << "Filling TTree" << endm; - mTree->Fill(); - } // if mGenTree -} - +} // FitVertex //________________________________________________________________________ void StFwdTrackMaker::Clear(const Option_t *opts) { LOG_DEBUG << "StFwdTrackMaker::CLEAR" << endm; mForwardData->clear(); + mForwardTracker->Clear(); + + // clear fwd hits from fst and ftt + mFwdHitsFst.clear(); + mFwdHitsFtt.clear(); + + // clear vectors for visualization OBJ hits + mFttHits.clear(); + mFstHits.clear(); + mFcsPreHits.clear(); + mFcsClusters.clear(); + mFwdTracks.clear(); - if (mGenTree){ - mTreeData.thdN = mTreeData.fttN = mTreeData.rcN = mTreeData.mcN = mTreeData.vmcN = mTreeData.vrcN = mTreeData.fcsN = 0; - mTreeData.fttX.clear(); - mTreeData.fttY.clear(); - mTreeData.fttZ.clear(); - mTreeData.fttTrackId.clear(); - mTreeData.fttVolumeId.clear(); - mTreeData.fttPt.clear(); - mTreeData.fttVertexId.clear(); - - mTreeData.fstX.clear(); - mTreeData.fstY.clear(); - mTreeData.fstZ.clear(); - mTreeData.fstTrackId.clear(); - - mTreeData.fcsX.clear(); - mTreeData.fcsY.clear(); - mTreeData.fcsZ.clear(); - mTreeData.fcsDet.clear(); - - mTreeData.rcPt.clear(); - mTreeData.rcEta.clear(); - mTreeData.rcPhi.clear(); - mTreeData.rcQuality.clear(); - mTreeData.rcTrackId.clear(); - mTreeData.rcNumFST.clear(); - mTreeData.rcCharge.clear(); - mTreeData.rcNumFTT.clear(); - mTreeData.rcNumPV.clear(); - - - mTreeData.mcPt.clear(); - mTreeData.mcEta.clear(); - mTreeData.mcPhi.clear(); - mTreeData.mcVertexId.clear(); - mTreeData.mcCharge.clear(); - mTreeData.vmcX.clear(); - mTreeData.vmcY.clear(); - mTreeData.vmcZ.clear(); - - mTreeData.tprojX.clear(); - mTreeData.tprojY.clear(); - mTreeData.tprojZ.clear(); - mTreeData.tprojPx.clear(); - mTreeData.tprojPy.clear(); - mTreeData.tprojPz.clear(); - mTreeData.vrcX.clear(); - mTreeData.vrcY.clear(); - mTreeData.vrcZ.clear(); - mTreeData.thdX.clear(); - mTreeData.thdY.clear(); - mTreeData.thaX.clear(); - mTreeData.thaY.clear(); - mTreeData.thaZ.clear(); - - mTreeData.thdX.clear(); - mTreeData.thdY.clear(); - mTreeData.thaX.clear(); - mTreeData.thaY.clear(); - mTreeData.thaZ.clear(); - - mTreeData.fttN = 0; - mTreeData.fstN = 0; - mTreeData.rcN = 0; - mTreeData.mcN = 0; - mTreeData.vmcN = 0; - mTreeData.tprojN = 0; - mTreeData.vrcN = 0; - mTreeData.thdN = 0; - } } //________________________________________________________________________ void StFwdTrackMaker::ProcessFwdTracks( ){ @@ -1699,9 +1417,7 @@ std::string StFwdTrackMaker::defaultConfigIdealSim = R"( - - - + @@ -1715,39 +1431,49 @@ std::string StFwdTrackMaker::defaultConfigData = R"( - + - + - - - - + + + + - + + - + - + 0.99 0.001 - + - - - + + + -)"; \ No newline at end of file +)"; + + +const std::vector &StFwdTrackMaker::getTrackSeeds() const{ + return mForwardTracker->getTrackSeeds(); +} + +const std::vector &StFwdTrackMaker::getFitResults()const{ + return mForwardTracker->getTrackResults(); +} diff --git a/StRoot/StFwdTrackMaker/StFwdTrackMaker.h b/StRoot/StFwdTrackMaker/StFwdTrackMaker.h index e04c158bb45..819b3ed0934 100644 --- a/StRoot/StFwdTrackMaker/StFwdTrackMaker.h +++ b/StRoot/StFwdTrackMaker/StFwdTrackMaker.h @@ -5,10 +5,12 @@ #ifndef __CINT__ #include "GenFit/Track.h" +#include "StFwdTrackMaker/include/Tracker/FwdHit.h" #endif #include "FwdTrackerConfig.h" #include "TVector3.h" +#include "TMatrix.h" namespace KiTrack { class IHit; @@ -38,67 +40,10 @@ class McTrack; // STL includes #include #include - - -// 877-369-6347 class StFwdTrack; class GenfitTrackResult; - -const size_t MAX_TREE_ELEMENTS = 4000; -struct FwdTreeData { - - // hits; - int fttN; - vector fttX, fttY, fttZ; - vector fttVolumeId; - // Only avalaible for hits if MC - vector fttPt; - vector fttTrackId, fttVertexId; - - // hits; - int fstN; - vector fstX, fstY, fstZ; - vector fstTrackId; - - int fcsN; - vector fcsX, fcsY, fcsZ; - vector fcsDet; - - // RC tracks - int rcN; - vector rcPt, rcEta, rcPhi, rcQuality; - vector rcTrackId, rcNumFST, rcCharge, rcNumFTT, rcNumPV; - - // MC Tracks - int mcN; - vector mcPt, mcEta, mcPhi; - vector mcVertexId, mcCharge; - - // MC Level vertex info - // maybe use also for TPC vertex if available in data - int vmcN; - vector vmcX, vmcY, vmcZ; - - int tprojN; - vector tprojX, tprojY, tprojZ; - vector tprojPx, tprojPy, tprojPz; - vector tprojIdD, tprojIdT; - - // RAVE reco vertices - int vrcN; - vector vrcX, vrcY, vrcZ; - - int thdN; - vector thdX, thdY, thaX, thaY, thaZ; - - bool saveCrit = false; - std::map> Crits; - std::map> CritTrackIds; - -}; - class StFwdTrackMaker : public StMaker { ClassDef(StFwdTrackMaker, 0); @@ -120,34 +65,41 @@ class StFwdTrackMaker : public StMaker { LoadConfiguration(); } void LoadConfiguration(); - void SetGenerateHistograms( bool _genHisto ){ mGenHistograms = _genHisto; } - void SetGenerateTree(bool _genTree) { mGenTree = _genTree; } void SetVisualize( bool _viz ) { mVisualize = _viz; } vector mFwdTracks; + vector &GetFttHits() { return mFwdHitsFtt; } + vector &GetFstHits() { return mFwdHitsFst; } + + #ifndef __CINT__ + // Get the FwdTracker object + std::shared_ptr GetForwardTracker() { return mForwardTracker; } + const std::vector &getTrackSeeds() const; + const std::vector &getFitResults() const; + #endif + TVector3 GetEventPrimaryVertex(); + private: protected: - // Track Seed typdef - typedef std::vector Seed_t; + // Event Filters + float mEventFilterMinTofMult = 2; + bool mEventFilterRequireEventVertex = false; + bool mEventFilterRequireVpdVertex = true; + float mEventFilterMinVpdZ = -99; + float mEventFilterMaxVpdZ = 99; - // for Wavefront OBJ export - size_t eventIndex = 0; - + size_t eventIndex = 0; // counts up for processed events + size_t mEventNum = 0; // global event num (index) + TVector3 mEventVertex; // primary vertex used in fwd tracking this event - bool mGenHistograms = false; - bool mGenTree = false; std::string mConfigFile; - std::map mHistograms; - TFile *mTreeFile = nullptr; - TTree *mTree = nullptr; - FwdTreeData mTreeData; - bool mVisualize = false; + bool mVisualize = false; // if true,write out a Wavefront OBJ to visualize the event in 3D vector mFttHits; vector mFstHits; vector mFcsClusters; @@ -155,175 +107,193 @@ class StFwdTrackMaker : public StMaker { vector mFcsPreHits; std::vector< genfit::GFRaveVertex * > mRaveVertices; + vector mFttZFromGeom, mFstZFromGeom; void ProcessFwdTracks(); void FillEvent(); void FillTrackDeltas(); + bool SkipEvent(); StFwdTrack * makeStFwdTrack( GenfitTrackResult >r, size_t indexTrack ); // I could not get the library generation to succeed with these. // so I have removed them #ifndef __CINT__ + TMatrixDSym mEventVertexCov; // covariance matrix for the primary vertex + enum FwdVertexSource { kFwdVertexSourceUnknown, kFwdVertexSourceNone, kFwdVertexSourceTpc, kFwdVertexSourceMc, kFwdVertexSourceVpd }; // unknown means we havent looked yet + FwdVertexSource mFwdVertexSource = StFwdTrackMaker::kFwdVertexSourceUnknown; + vector mFwdHitsFtt; + vector mFwdHitsFst; std::shared_ptr mSiRasterizer; FwdTrackerConfig mFwdConfig; std::shared_ptr mForwardTracker; std::shared_ptr mForwardData; - size_t loadMcTracks( std::map> &mcTrackMap ); void loadFcs(); void loadFttHits( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); void loadFttHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); void loadFttHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); - void loadFstHits( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); - void loadFstHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); - void loadFstHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); + int loadFstHits( std::map> &mcTrackMap, std::map> &hitMap ); + int loadFstHitsFromMuDst( std::map> &mcTrackMap, std::map> &hitMap ); + int loadFstHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap ); + int loadFstHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap ); + int loadFstHitsFromStRnDHits( std::map> &mcTrackMap, std::map> &hitMap ); #endif - void FillTTree(); // if debugging ttree is turned on (mGenTree) + + /** @brief Fit the primary vertex using FWD tracks */ void FitVertex(); static std::string defaultConfigIdealSim; static std::string defaultConfigData; std::string defaultConfig; bool configLoaded = false; + TString mGeoCache; // Helper functions for modifying configuration // NOTE: to override configuration, call individual functions after setConfigForXXX public: - /**@brief Setup the StFwdTrackMaker for running on Data - * Load the default configuration for Data. + /** @brief Setup the StFwdTrackMaker for running on Data + * Load the default configuration for Data. * Note: Apply any overrides after calling this */ void setConfigForData() { defaultConfig = defaultConfigData; LoadConfiguration(); } - /**@brief Setup the StFwdTrackMaker for running on Data + /** @brief Setup the StFwdTrackMaker for running on Data * Load the default configuration for IDEAL simulation. * This runs with MC track finding and MC-seeded track fitting. - * - MC track finding uses the MCTrackId to collect stgc/fst hits into track seeds + * - MC track finding uses the MCTrackId to collect stgc/fst hits into track seeds * - MC-seeded track fitting uses the MC particle momentum to seed the track fit * - Also uses the simulated MC primary vertex with smearing according to the simgaXY,Z * Note: Apply any overrides after calling this */ void setConfigForIdealSim() { defaultConfig = defaultConfigIdealSim; LoadConfiguration(); } - /**@brief Setup the StFwdTrackMaker for running on Data + /** @brief Setup the StFwdTrackMaker for running on Data * Load the default configuration for Realistic simulation. * This runs tracking on simulation using the same parameters / approach as on data. * Note: Apply any overrides after calling this */ - void setConfigForRealisticSim() { - defaultConfig = defaultConfigData; - LoadConfiguration(); + void setConfigForRealisticSim() { + defaultConfig = defaultConfigData; + LoadConfiguration(); // Note: Once the slow sims work this override will not be needed // because the slow sims will put hits into StEvent just like (data) reco chain setFttHitSource( "GEANT" ); } - /**@brief Set the filename for output ROOT file + /** @brief Set the filename for output ROOT file * @param fn : filename of output ROOT file */ void setOutputFilename( std::string fn ) { mFwdConfig.set( "Output:url", fn ); } - /**@brief Set the data source for FTT hits - * + /** @brief Set the data source for FTT hits + * * @param source : {DATA, GEANT}, DATA means read from StEvent, GEANT means read directly from the GEANT hits */ void setFttHitSource( std::string source ) { mFwdConfig.set( "Source:ftt", source ); } - - /**@brief Enable or disable the Fst Rasterizer + + /** @brief Enable or disable the Fst Rasterizer * @param use : if true, load FST hits from GEANT and raster them according to r, phi resolutions. */ void setUseFstRasteredGeantHits( bool use = true ){ mFwdConfig.set( "SiRasterizer:active", use ); } - /**@brief Set the resolution in R for rasterizing FST hits (from fast sim) + /** @brief Set the resolution in R for rasterizing FST hits (from fast sim) * Only used when the Rasterizer is enabled, which results from reading FST hits from GEANT * @param r : resolution in r (cm) */ void setFstRasterR( double r = 3.0 /*cm*/ ){ mFwdConfig.set( "SiRasterizer:r", r ); } - /**@brief Set the resolution in phi for rasterizing FST hits (from fast sim) + /** @brief Set the resolution in phi for rasterizing FST hits (from fast sim) * Only used when the Rasterizer is enabled, which results from reading FST hits from GEANT * @param phi : resolution in phi (rad) */ void setFstRasterPhi( double phi = 0.00409 /*2*pi/(12*128)*/ ){ mFwdConfig.set( "SiRasterizer:phi", phi ); } //Track Finding - /**@brief Use Ftt hits in the Seed Finding - * + /** @brief Use FST and Ftt hits (sequentially) in the Seed Finding - then merge tracks + * + */ + void setSeedFindingWithFstFttSequential() { mFwdConfig.set( "TrackFinder:source", "seq" ); } + /** @brief Use FST and Ftt hits (simultaneously) in the Seed Finding + * + */ + void setSeedFindingWithFstFttSimultaneous() { mFwdConfig.set( "TrackFinder:source", "sim" ); } + /** @brief Use Ftt hits in the Seed Finding + * */ void setSeedFindingWithFtt() { mFwdConfig.set( "TrackFinder:source", "ftt" ); } - /**@brief Use Fst hits in the Seed Finding - * + /** @brief Use Fst hits in the Seed Finding + * */ void setSeedFindingWithFst() { mFwdConfig.set( "TrackFinder:source", "fst" ); } - /**@brief Set the number of track finding iterations + /** @brief Set the number of track finding iterations * @param n : number of iterations to run */ void setSeedFindingNumInterations( int n = 1 ) { mFwdConfig.set("TrackFinder:nIterations", n); } - /**@brief Set the number of phi slices to split the track iterations into + /** @brief Set the number of phi slices to split the track iterations into * @param n : number of slices of equal size (2pi)/n */ void setSeedFindingNumPhiSlices( int n = 8 ) { mFwdConfig.set("TrackFinder.Iteration:nPhiSlices", n); } - /**@brief Set the connector distance for track finding + /** @brief Set the connector distance for track finding * @param d : distance between planes (1 = adjacent) */ void setSeedFindingConnectorDistance( int d = 1 ) { mFwdConfig.set( "TrackFinder.Connector:distance", d ); } - /**@brief Enable or disable the SubsetNN + /** @brief Enable or disable the SubsetNN * @param use : if true, enables the subsetNN which find the most compatible set of tracks without shared hits * if false, all tracks are reported regardless of shared hits */ void setSeedFindingUseSubsetNN( bool use = true ) { mFwdConfig.set( "TrackFinder.SubsetNN:active", use ); } - /**@brief Enable or disable the SubsetNN + /** @brief Enable or disable the SubsetNN * @param n : minimum number of hits on a track seed. Seeds with fewer hits are discarded */ void setSeedFindingMinHitsOnTrack( int n = 3 ) { mFwdConfig.set( "TrackFinder.SubsetNN:min-hits-on-track", n ); } - /**@brief Enable or disable the HitRemover + /** @brief Enable or disable the HitRemover * @param use : if true, enables the hit remover which removes any hits from the hitmap that were used in a track * if false, hits are not removed after each iteration */ void setSeedFindingUseHitRemover( bool use = true ) { mFwdConfig.set( "TrackFinder.HitRemover:active", use ); } - /**@brief Enable or disable the Truth Seed finding + /** @brief Enable or disable the Truth Seed finding * @param use : if true, use Mc info to group hits into track seeds * if false, seed finding uses options as in the case for data */ void setUseTruthSeedFinding( bool use = true ) { mFwdConfig.set( "TrackFinder:active", !use ); } // Track Fitting - /**@brief Turn off track fitting + /** @brief Turn off track fitting * Useful if you want to speed up the run but dont need fitting (testing seed finding) */ void setTrackFittingOff() { mFwdConfig.set( "TrackFitter:active", "false" ); } - /**@brief Enable / disable material effects + /** @brief Enable / disable material effects * Material effects in kalman filter */ void setFittingMaterialEffects( bool mat = true) { mFwdConfig.set( "TrackFitter:materialEffects", mat ); } - /**@brief Set the resolution for the Primary Vertex in XY + /** @brief Set the resolution for the Primary Vertex in XY * @params sXY : sigma in XY (cm) */ void setPrimaryVertexSigmaXY( double sXY ) { mFwdConfig.set( "TrackFitter.Vertex:sigmaXY", sXY ); } - /**@brief Set the resolution for the Primary Vertex in Z + /** @brief Set the resolution for the Primary Vertex in Z * @params sZ : sigma in Z (cm) */ void setPrimaryVertexSigmaZ( double sZ ) { mFwdConfig.set( "TrackFitter.Vertex:sigmaZ", sZ ); } // TODO: add options for beamline constraint - /**@brief Include or exclude the Primary Vertex in fit + /** @brief Include or exclude the Primary Vertex in fit * @param pvf : if true, use PRimary Vertex in fit */ void setIncludePrimaryVertexInFit( bool pvf = true ) { mFwdConfig.set( "TrackFitter.Vertex:includeInFit", pvf ); } - /**@brief Set B-field to zero (for zero field running) + /** @brief Set B-field to zero (for zero field running) * @param zeroB : if true, use Zero B field */ void setZeroB( bool zeroB = true ) { mFwdConfig.set( "TrackFitter:zeroB", zeroB ); } - /**@brief Set B-field to constant (even outside of TPC) + /** @brief Set B-field to constant (even outside of TPC) * @param constB : if true, use const 0.5T B field */ void setConstB( bool constB = true ) { mFwdConfig.set( "TrackFitter:constB", constB ); } - /**@brief Force the use of McSeed for fit + /** @brief Force the use of McSeed for fit * @param mcSeed : if true, use mc momentum as the seed for the track fitter */ void setUseMcSeedForFit( bool mcSeed = true ) { mFwdConfig.set( "TrackFitter:mcSeed", mcSeed ); } - /**@brief Sets the tracking to refit + /** @brief Sets the tracking to refit * This adds compatible hits from whichever detector was NOT used in seed finding * if FTT seeding -> project to and add FST hits * if FST seeding -> project to and add FTT hits @@ -331,28 +301,81 @@ class StFwdTrackMaker : public StMaker { */ void setTrackRefit( bool refit = true) { mFwdConfig.set( "TrackFitter:refit", refit ); } - /**@brief Sets the maximum number of hits that can be considered failed before the entire track fit fails + /** @brief Sets the maximum number of hits that can be considered failed before the entire track fit fails * @param n : number of failed hits allowed, -1 = no limit */ void setMaxFailedHitsInFit( int n = -1 /*no lim*/ ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MaxFailedHits", n);} - /**@brief Sets Fitter debug level + /** @brief Sets Fitter debug level * @param level : 0 = no output, higher numbers are more verbose */ void setFitDebugLvl( int level = 0 /*0=no output*/ ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:DebugLvl", level); } - /**@brief Sets Max fit iterations before failing + /** @brief Sets Max fit iterations before failing * @param n : num iterations */ void setFitMaxIterations( int n=4 ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MaxIterations", n); } - /**@brief Sets Min fit iterations before converging + /** @brief Sets Min fit iterations before converging * @param n : num iterations */ void setFitMinIterations( int n = 1) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MinIterations", n); } - /**@brief Enables smearing of the MC Primary Vertex according to sigmaXY,Z - * @param pvs : if true, smear vertex + /** @brief Enables smearing of the MC Primary Vertex according to sigmaXY,Z + * @param pvs : if true, smear vertex */ void setSmearMcPrimaryVertex( bool pvs = true ) { mFwdConfig.set( "TrackFitter.Vertex:smearMcVertex", pvs ); } - + + /** + * @brief Sets geometry cache filename + * + */ + void setGeoCache( TString gc ) { mGeoCache = gc; } + + /** + * @brief Set a generic Key Value in the Config object + * + * @param k key: any string representing absolute path e.g. `the.path.to.node:attribute` + * @param v value: value encoded as a string + */ + void setConfigKeyValue( std::string k, std::string v ){ + mFwdConfig.set( k, v ); + } + + /** @brief Sets a criteria value in the config for 2-hit criteria + * @param string name: name of the crit2, e.g. Crit2_RZRatio + * @param double min: minimum for the criteria, meaning depends on specific crit2 + * @param double max: maximum for the criteria, meaning depends on specific crit2 + */ + void setCrit2( std::string name, double min, double max ){ + for ( auto p : mFwdConfig.childrenOf( "TrackFinder.Iteration.SegmentBuilder" ) ){ + auto nName = mFwdConfig.get( p + ":name", "DNE" ); + if (nName == name) { + LOG_DEBUG << "Setting Crit2=" << nName << " (min=" << min << ", max=" << max << ")" << endm; + mFwdConfig.set(p + ":min", min ); + mFwdConfig.set(p + ":max", max ); + return; + } + } // loop on existing crit2 + // if we got here then the crit did not exist + + } + + /** @brief Sets a criteria value in the config for 3-hit criteria + * @param string name: name of the crit3, e.g. Crit2_RZRatio + * @param double min: minimum for the criteria, meaning depends on specific crit2 + * @param double max: maximum for the criteria, meaning depends on specific crit2 + */ + void setCrit3( std::string name, double min, double max ){ + for ( auto p : mFwdConfig.childrenOf( "TrackFinder.Iteration.ThreeHitSegments" ) ){ + auto nName = mFwdConfig.get( p + ":name", "DNE" ); + if (nName == name) { + LOG_DEBUG << "Setting Crit3=" << nName << " (min=" << min << ", max=" << max << ")" << endm; + mFwdConfig.set(p + ":min", min ); + mFwdConfig.set(p + ":max", max ); + return; + } + } // loop on existing crit3 + // if we got here then the crit did not exist + } + }; #endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h b/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h new file mode 100644 index 00000000000..bc608886d1b --- /dev/null +++ b/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h @@ -0,0 +1,144 @@ +#ifndef FITTERUTILS_H +#define FITTERUTILS_H + +#include "GenFit/KalmanFitter.h" +#include "GenFit/KalmanFitterInfo.h" +#include "GenFit/KalmanFitterRefTrack.h" +#include "GenFit/MaterialEffects.h" +#include "GenFit/PlanarMeasurement.h" +#include "GenFit/RKTrackRep.h" +#include "GenFit/SpacepointMeasurement.h" +#include "GenFit/StateOnPlane.h" +#include "GenFit/TGeoMaterialInterface.h" +#include "GenFit/Track.h" +#include "GenFit/TrackPoint.h" + +#include "TVector3.h" + + +class FitSeedMaker { + public: + FitSeedMaker() {} + virtual ~FitSeedMaker() {} + virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) = 0; +}; +class ConstFitSeeder : public FitSeedMaker { + public: + ConstFitSeeder() {} + virtual ~ConstFitSeeder() {} + virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) { + posSeed.SetXYZ(0,0,0); + momSeed.SetXYZ(0,0,10); + q = 1; + } +}; +class GenericFitSeeder : public FitSeedMaker { + public: + GenericFitSeeder() {} + virtual ~GenericFitSeeder() {} + // Simple function to calculate the determinant of a 2x2 matrix + inline double determinant(double a, double b, double c, double d) { + return a * d - b * c; + } + struct Point { + double x, y; + }; + // Function to compute the curvature of a circle given 3 points + double computeSignedCurvature(const Point& p1, const Point& p2, const Point& p3) { + // Calculate the lengths of the sides of the triangle + double A = std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2)); + double B = std::sqrt(std::pow(p3.x - p2.x, 2) + std::pow(p3.y - p2.y, 2)); + double C = std::sqrt(std::pow(p1.x - p3.x, 2) + std::pow(p1.y - p3.y, 2)); + + // Calculate the determinant of the matrix formed by the points + double det = determinant(p2.x - p1.x, p2.y - p1.y, p3.x - p1.x, p3.y - p1.y); + // LOG_INFO << "Det: " << det << endm; + double charge = det > 0 ? -1 : 1; + // Area of the triangle formed by the three points + double area = std::abs(det) / 2.0; + + if (area == 0) { + std::cerr << "The points are collinear, curvature is undefined." << std::endl; + return -1; // Curvature is undefined for collinear points + } + + // Calculate the radius of the circumcircle using the formula: + // R = (A * B * C) / (4 * area) + double radius = (A * B * C) / (4 * area); + // LOG_INFO << "Radius: " << radius << endm; + // Curvature is the inverse of the radius + return charge / radius; + } + // Function to compute the average curvature for all combinations of 3 points + double averageCurvature( const Seed_t points ) { + // const std::vector& points; + int numPoints = points.size(); + if (numPoints < 3) { + std::cerr << "Not enough points to form a circle." << std::endl; + return -1; + } + + double totalCurvature = 0.0; + int validCombinations = 0; + + // Iterate over all combinations of 3 points + for (int i = 0; i < numPoints - 2; ++i) { + for (int j = i + 1; j < numPoints - 1; ++j) { + for (int k = j + 1; k < numPoints; ++k) { + Point p0 = {points[i]->getX(), points[i]->getY()}; + Point p1 = {points[j]->getX(), points[j]->getY()}; + Point p2 = {points[k]->getX(), points[k]->getY()}; + double curvature = computeSignedCurvature(p0, p1, p2); + if (curvature != -1) { // Exclude invalid (collinear) combinations + totalCurvature += curvature; + ++validCombinations; + } + } + } + } + + if (validCombinations == 0) { + std::cerr << "No valid curvature calculations possible." << std::endl; + return -1; // No valid triangles were found + } + + return totalCurvature / validCombinations; + } + + template int sgn(T val) { + return (T(0) < val) - (val < T(0)); + } + virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) { + const double qc = averageCurvature(seed); + posSeed.SetXYZ(0,0,0); + momSeed.SetXYZ(0,0,10); + + const double BStrength = 0.5; // 0.5 T + const double C = 0.3 * BStrength; //C depends on the units used for momentum and Bfield (here GeV and Tesla) + const double K = 0.00029979; // K depends on the units used for Bfield and momentum (here Gauss and GeV) + double pt = fabs((K*5)/qc); // pT from average measured curv + + // set the momentum seed's transverse momentum + momSeed.SetPerp(pt); + // compute the seed's eta from seed points + TVector3 p0 = TVector3(seed[0]->getX(), seed[0]->getY(), seed[0]->getZ()); + TVector3 p1 = TVector3(seed[1]->getX(), seed[1]->getY(), seed[1]->getZ()); + double dx = (p1.X() - p0.X()); + double dy = (p1.Y() - p0.Y()); + double dz = (p1.Z() - p0.Z()); + double phi = TMath::ATan2(dy, dx); + double Rxy = sqrt(dx * dx + dy * dy); + double theta = TMath::ATan2(Rxy, dz); + if (abs(dx) < 1e-6 || abs(dy) < 1e-6){ + phi = TMath::ATan2( p1.Y(), p1.X() ); + } + + // momSeed.SetPhi(phi); + // momSeed.SetTheta(theta); + + // assign charge based on sign of curvature + q = sgn(qc); + } +}; + +#endif \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h index c26fabd95ae..a94eeca9f4d 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h @@ -32,27 +32,11 @@ class FwdDataSource { // Cleanup void clear() { - - // delete the hits from the hitmap - for ( auto kv : mFttHits ){ - for ( auto h : kv.second ){ - delete h; - } - kv.second.clear(); - } - - for ( auto kv : mFstHits ){ - for ( auto h : kv.second ){ - delete h; - } - kv.second.clear(); - } - - // the tracks are shared pointers, so they will be taken care of by clearing the map (below) - - mFttHits.clear(); - mFstHits.clear(); - mMcTracks.clear(); + // Just empty our vectors, we dont own the memory + mFttHits.clear(); + mFstHits.clear(); + // the tracks are shared pointers, so they will be taken care of by clearing the map (below) + mMcTracks.clear(); } // TODO, protect and add interaface for pushing hits / tracks diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h index 93e6de702b7..9d928fa7457 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h @@ -9,13 +9,19 @@ class FwdGeomUtils { public: + + FwdGeomUtils( TGeoManager * gMan ) { - if ( gMan != nullptr ) + if ( gMan != nullptr ){ _navigator = gMan->AddNavigator(); + _gMan = gMan; + } } ~FwdGeomUtils(){ - + if ( _gMan != nullptr && _navigator != nullptr){ + _gMan->RemoveNavigator( _navigator ); + } } bool cd( const char* path ){ @@ -43,11 +49,11 @@ class FwdGeomUtils { } double fttZ( int index ) { - // This ftt_z_delta is needed to match the z location of hits (midpint of active volume?) to the z location of the mother volume. + // This ftt_z_delta is needed to match the z location of hits (midpint of active volume?) to the z location of the mother volume. // NOTE: It may be possible to improve this when the higher precision FTT geometry model is added const double ftt_z_delta = -0.5825245; stringstream spath; - spath << "/HALL_1/CAVE_1/STGM_1/STFM_" << (index + 1) * 4 << "/"; + spath << "/HALL_1/CAVE_1/STGM_1/STFM_" << (index + 1) * 4 << "/"; bool can = cd( spath.str().c_str() ); if ( can && _matrix != nullptr ){ return _matrix->GetTranslation()[2] + ftt_z_delta; @@ -69,12 +75,12 @@ class FwdGeomUtils { // the index are now 4,5,6 // hence +4 below // also fixed typo, previously was incorrectly FTSD_ - + const double z_delta = 1.755; stringstream spath; - spath << "/HALL_1/CAVE_1/FSTM_1/FSTD_" << (index + 4) << "/"; + spath << "/HALL_1/CAVE_1/FSTM_1/FSTD_" << (index + 4) << "/"; bool can = cd( spath.str().c_str() ); if ( can && _matrix != nullptr ){ - return _matrix->GetTranslation()[2]; + return _matrix->GetTranslation()[2] + z_delta; } return 0.0; } @@ -85,6 +91,7 @@ class FwdGeomUtils { TGeoHMatrix *_matrix = nullptr; TGeoIterator *_iter = nullptr; TGeoNavigator *_navigator = nullptr; + TGeoManager *_gMan = nullptr; }; -#endif \ No newline at end of file +#endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h index bcf4cb1fa7b..bc44ea71548 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h @@ -11,6 +11,8 @@ #include #include +#include "StEvent/StEnumerations.h" + class StHit; class FwdSystem : public KiTrack::ISectorSystem { @@ -20,7 +22,7 @@ class FwdSystem : public KiTrack::ISectorSystem { static const int sNFstLayers = 3; FwdSystem(const int ndisks = FwdSystem::sNFwdLayers) : KiTrack::ISectorSystem(), mNDisks(ndisks){}; ~FwdSystem(){/* */}; - virtual unsigned int getLayer(int diskid) const throw(KiTrack::OutOfRange) { + virtual unsigned int getLayer(int diskid) const { return diskid; } @@ -50,14 +52,14 @@ class McTrack { mStartVertex = start_vertex; } - void addHit(KiTrack::IHit *hit) { mHits.push_back(hit); } - // void addFstHit(KiTrack::IHit *hit) { mFstHits.push_back(hit); } + void addFttHit(KiTrack::IHit *hit) { mFttHits.push_back(hit); } + void addFstHit(KiTrack::IHit *hit) { mFstHits.push_back(hit); } double mPt, mEta, mPhi; int mTid, mQ, mStartVertex; - std::vector mHits; - // std::vector mFstHits; + std::vector mFttHits; + std::vector mFstHits; }; @@ -67,13 +69,28 @@ class McTrack { */ class FwdHit : public KiTrack::IHit { public: - FwdHit(unsigned int id, float x, float y, float z, int vid, int tid, - TMatrixDSym covmat, std::shared_ptr mcTrack = nullptr ) + // Default ctor + FwdHit() : KiTrack::IHit() { + _id = 0; + _x = 0; + _y = 0; + _z = 0; + _detid = 0; + _tid = 0; + _vid = 0; + _sector = 0; + _mcTrack = nullptr; + _hit = 0; + _covmat.ResizeTo( 3, 3 ); + }; + FwdHit(unsigned int id, float x, float y, float z, int vid, int detid, int tid, + TMatrixDSym covmat, std::shared_ptr mcTrack ) : KiTrack::IHit() { _id = id; _x = x; _y = y; _z = z; + _detid = detid; _tid = tid; _vid = vid; _mcTrack = mcTrack; @@ -94,13 +111,29 @@ class FwdHit : public KiTrack::IHit { } }; + // Set basic props for e.g. Primary Vertex type hits + void setXYZDetId( float x, float y, float z, int detid ){ + _x = x; + _y = y; + _z = z; + _detid = detid; + } + + bool isFst() const { return _detid == kFstId; } + bool isFtt() const { return _detid == kFttId; } + bool isPV() const { return _detid == kTpcId; } + + std::shared_ptr getMcTrack() { return _mcTrack; } + const KiTrack::ISectorSystem *getSectorSystem() const { return FwdSystem::sInstance; } + void setSector( int s ){ _sector = s; } int getTrackId() { return _tid;} int _tid; // aka ID truth int _vid; // volume id + int _detid; // detector id unsigned int _id; // just a unique id for each hit in this event. std::shared_ptr _mcTrack; TMatrixDSym _covmat; @@ -108,7 +141,8 @@ class FwdHit : public KiTrack::IHit { StHit *_hit; }; -using Seed_t = std::vector; +// Track Seed typdef +typedef std::vector Seed_t; class FwdConnector : public KiTrack::ISectorConnector { public: diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h index 1316f9eca61..531faf43eeb 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h @@ -10,18 +10,18 @@ #include "TRandom3.h" #include "TTree.h" #include "TVector3.h" +#include "TLorentzVector.h" #include #include #include #include #include +#include #include "StFwdTrackMaker/include/Tracker/FwdHit.h" #include "StFwdTrackMaker/include/Tracker/FwdDataSource.h" -#include "StFwdTrackMaker/include/Tracker/QualityPlotter.h" #include "StFwdTrackMaker/include/Tracker/TrackFitter.h" -#include "StFwdTrackMaker/include/Tracker/BDTCriteria.h" #include "Criteria/Criteria.h" #include "Criteria/ICriterion.h" @@ -41,7 +41,7 @@ struct MCTruthUtils { static int dominantContribution(Seed_t hits, double &qa) { - + // track_id, hits on track std::unordered_map truth; for ( auto hit : hits ) { @@ -49,6 +49,10 @@ struct MCTruthUtils { truth[ fhit->_tid ]++; } + if ( truth.size() == 0 ){ + return -1; + } + using namespace std; using P = decltype(truth)::value_type; auto dom = max_element(begin(truth), end(truth), [](P a, P b){ return a.second < b.second; }); @@ -57,139 +61,222 @@ struct MCTruthUtils { // vote the same way on the track if ( hits.size() > 0 ) qa = double(dom->second) / double(hits.size()) ; - else + else qa = 0; return dom->first; }; }; +class EventStats { + public: + TString classname() const { return "EventStats"; } + void reset(){ + mNumSeeds = 0; + mAttemptedFits = 0; + mFailedFits = 0; + mGoodFits = 0; + mGoodCardinals = 0; + + mAttemptedReFits = 0; + mFailedReFits = 0; + mGoodReFits = 0; + mPossibleReFit = 0; + + mNumFwdVertices = 0; + mAttemptedPrimaryFits = 0; + mGoodPrimaryFits = 0; + mFailedPrimaryFits = 0; + + mStep1Duration.clear(); + mStep2Duration.clear(); + mStep3Duration.clear(); + mStep4Duration.clear(); + mFitDuration.clear(); + } + int mNumSeeds = 0; + int mAttemptedFits = 0; + int mFailedFits = 0; + int mGoodFits = 0; + int mGoodCardinals = 0; + + int mAttemptedReFits = 0; + int mFailedReFits = 0; + int mGoodReFits = 0; + int mPossibleReFit = 0; + + int mNumFwdVertices = 0; + int mAttemptedPrimaryFits = 0; + int mGoodPrimaryFits = 0; + int mFailedPrimaryFits = 0; + vector mStep1Duration; + vector mSeedFindingDuration; + vector mStep2Duration; + vector mStep3Duration; + vector mStep4Duration; + vector mFitDuration; +}; + class GenfitTrackResult { public: - GenfitTrackResult( size_t nFTT, size_t nFST, - Seed_t &seedTrack, genfit::Track *track ) { - this->nFST = nFST; - this->nFTT = nFTT; - this->trackSeed = seedTrack; - + GenfitTrackResult(){} + GenfitTrackResult( Seed_t &seed, std::shared_ptr track ) { + set( seed, track ); + } + ~GenfitTrackResult(){ + // Clear(); + } + void Clear() { + if ( mTrack ){ + mTrack->Clear(); + } + } + void set( Seed_t &seeds, std::shared_ptr track ){ + setSeed( seeds ); + setTrack( track ); + } + void setSeed( Seed_t &seed ){ + mSeed = seed; + mIdTruth = MCTruthUtils::dominantContribution( seed, mQaTruth ); + LOG_INFO << "GenFitTrackResult::mIdTruth = " << mIdTruth << ", QaTruth = " << mQaTruth << endm; + } + void setTrack( std::shared_ptr track ){ try { - this->track = track; - this->status = *(this->track->getFitStatus()); - this->trackRep = this->track->getCardinalRep(); - - this->isFitConverged = this->status.isFitConverged(); - this->isFitConvergedFully = this->status.isFitConvergedFully(); - this->isFitConvergedPartially = this->status.isFitConvergedPartially(); - this->nFailedPoints = this->status.getNFailedPoints(); - this->charge = this->status.getCharge(); - - this->nPV = this->track->getNumPoints() - (nFTT + nFST); - - this->momentum = this->trackRep->getMom( this->track->getFittedState(0, this->trackRep) ); + // this->track = new genfit::Track(*track); + mTrack = track; + mTrack ->setMcTrackId(mIdTruth); + mStatus = mTrack->getFitStatus(); + mTrackRep = mTrack->getCardinalRep(); + + mIsFitConverged = mStatus->isFitConverged(); + mIsFitConvergedFully = mStatus->isFitConvergedFully(); + mIsFitConvergedPartially = mStatus->isFitConvergedPartially(); + mNFailedPoints = mStatus->getNFailedPoints(); + mCharge = mStatus->getCharge(); + mChi2 = mStatus->getChi2(); + + if ( mIsFitConverged ){ + LOG_INFO << "GTR Setting momentum from track" << endm; + mMomentum = mTrackRep->getMom( mTrack->getFittedState(0, mTrackRep) ); + } LOG_DEBUG << "GenfitTrackResult::set Track successful" << endm; - } catch ( genfit::Exception &e ) { - LOG_ERROR << "GenfitTrackResult cannot get track" << endm; - this->track = nullptr; - this->trackRep = nullptr; - - this->isFitConverged = false; - this->isFitConvergedFully = false; - this->isFitConvergedPartially = false; - this->nFailedPoints = nFST + nFTT; - this->charge = 0; + LOG_ERROR << "Unable to set track -> GenfitException: " << e.what() << endm; + this->mTrack = nullptr; + this->mTrackRep = nullptr; + + this->mIsFitConverged = false; + this->mIsFitConvergedFully = false; + this->mIsFitConvergedPartially = false; + this->mNFailedPoints = 99; + this->mCharge = 0; + this->mChi2 = -1; } } - ~GenfitTrackResult() { - // MEMORY LEAK - // LOG_INFO << "~GenfitTrackResult" << endm; - // if (this->track) - // delete this->track; - // this->track = nullptr; - } - - void setFst( Seed_t &seedFst, genfit::Track *track ){ - LOG_DEBUG << "GenfitTrackResult::setFSt" << endm; - nFST = seedFst.size(); - fstSeed = seedFst; - - try { - this->fstTrack = new genfit::Track(*track); - // make sure the McTrackId is set correctly - this->fstTrack->setMcTrackId( this->track->getMcTrackId() ); - this->fstStatus = *(this->fstTrack->getFitStatus()); - this->fstTrackRep = this->fstTrack->getCardinalRep(); - - this->isFitConverged = this->fstStatus.isFitConverged(); - this->isFitConvergedFully = this->fstStatus.isFitConvergedFully(); - this->isFitConvergedPartially = this->fstStatus.isFitConvergedPartially(); - this->nFailedPoints = this->fstStatus.getNFailedPoints(); - this->charge = this->fstStatus.getCharge(); - this->fstMomentum = this->fstTrackRep->getMom( this->fstTrack->getFittedState(0, this->fstTrackRep) ); + /** @brief Set the DCA and primary vertex for the event + * + */ + void setDCA( TVector3 pv ){ + mPV = pv; + if ( mTrack ){ + try { + auto dcaState = mTrack->getFittedState( 0 ); + this->mTrackRep->extrapolateToPoint( dcaState, mPV ); + this->mDCA = dcaState.getPos(); + } catch ( genfit::Exception &e ) { + LOG_ERROR << "CANNOT GET DCA : GenfitException: " << e.what() << endm; + this->mDCA = TVector3(99,99,99); + } - } catch ( genfit::Exception &e ) { - LOG_ERROR << "CANNOT GET FST TRACK" << endm; - this->fstTrack = nullptr; - this->fstTrackRep = nullptr; - - this->fstIsFitConverged = false; - this->fstIsFitConvergedFully = false; - this->fstIsFitConvergedPartially = false; - this->fstNFailedPoints = nFST + nFTT; - this->fstCharge = 0; } } + size_t numFtt() const { + size_t n = 0; + for ( auto hit : mSeed ){ + if ( dynamic_cast(hit)->_detid == kFttId ){ + n++; + } + } + return n; + } + size_t numFst() const { + size_t n = 0; + for ( auto hit : mSeed ){ + if ( dynamic_cast(hit)->_detid == kFstId ){ + n++; + } + } + return n; + } + size_t numPV() const { + size_t n = 0; + for ( auto hit : mSeed ){ + if ( dynamic_cast(hit)->isPV() ){ + n++; + } + } + return n; + } - Seed_t trackSeed; - Seed_t fstSeed; - TVector3 momentum; - double charge; - size_t nFST = 0; - size_t nFTT = 0; - size_t nPV = 0; - genfit::FitStatus status; - genfit::AbsTrackRep *trackRep = nullptr; - genfit::Track *track = nullptr; - bool isFitConverged = false; - bool isFitConvergedFully = false; - bool isFitConvergedPartially = false; - size_t nFailedPoints = 0; - - // Result after FST refit - genfit::Track *fstTrack = nullptr; - genfit::AbsTrackRep *fstTrackRep = nullptr; - genfit::FitStatus fstStatus; - bool fstIsFitConverged = false; - bool fstIsFitConvergedFully = false; - bool fstIsFitConvergedPartially = false; - size_t fstNFailedPoints = 0; - double fstCharge = 0; - TVector3 fstMomentum; - - void summary() { - LOG_INFO << TString::Format( "TrackResult[p=(%f, %f, %f)/(%f, %f, %f), q=%f, nFTT=%lu, nFST=%lu, nPV=%lu, isFitConvergedFully=%d]", momentum.X(), momentum.Y(), momentum.Z(), momentum.Pt(), momentum.Eta(), momentum.Phi(), charge, nFTT, nFST, nPV, isFitConvergedFully ).Data() << endm; + void mergeSeeds( GenfitTrackResult &other ){ + // combine the unique Ftt and Fst seeds + for ( auto hit : other.mSeed ){ + if ( std::find( mSeed.begin(), mSeed.end(), hit ) == mSeed.end() ){ + mSeed.push_back( hit ); + } + } } -}; + + bool isPrimary = false; + Seed_t mSeed; + TVector3 mPV; // as a TVector3 + TVector3 mMomentum; + float mCharge = 0; + float mChi2 = -1; + genfit::FitStatus *mStatus = nullptr; + genfit::AbsTrackRep *mTrackRep = nullptr; + std::shared_ptr mTrack = nullptr; + bool mIsFitConverged = false; + bool mIsFitConvergedFully = false; + bool mIsFitConvergedPartially = false; + size_t mNFailedPoints = 0; + TVector3 mDCA; + int mIdTruth = -1; + double mQaTruth = 0; +}; // GenfitTrackResult class ForwardTrackMaker { public: ForwardTrackMaker() : mConfigFile("config.xml"), mEventVertex(-999, -999, -999) { // noop } - + const std::vector &getTrackResults() const { return mTrackResults; } - const std::vector &getRecoTracks() const { return mRecoTracks; } - const std::vector &getFitMomenta() const { return mFitMoms; } - const std::vector &getNumFstHits() const { return mNumFstHits; } - const std::vector &getFitStatus() const { return mFitStatus; } - const std::vector &globalTrackReps() const { return mGlobalTrackReps; } - const std::vector &globalTracks() const { return mGlobalTracks; } + const std::vector &getTrackSeeds() const { return mTrackSeeds; } + const EventStats &getEventStats() const { return mEventStats; } + + void Clear(){ + for ( auto gtr : mTrackResults ){ + gtr.Clear(); + } + mTrackResults.clear(); + } + /** + * @brief Set the Config File object + * + * @param cf : config filename + */ void setConfigFile(std::string cf) { mConfigFile = cf; } + /** + * @brief Set the Save Criteria Values object + * + * @param save : true to save crit values + */ void setSaveCriteriaValues(bool save) { mSaveCriteriaValues = save; } @@ -199,44 +286,26 @@ class ForwardTrackMaker { // Adopt external hit loader void setData(std::shared_ptrdata) { mDataSource = data; } + /** + * @brief Initialize FwdTracker + * + * @param geoCache : name of cached geometry file + * @param genHistograms : generate histograms + */ virtual void initialize( TString geoCache, bool genHistograms) { - mGenHistograms = genHistograms; - if (mGenHistograms) setupHistograms(); - mGeoCache = geoCache; - mDoTrackFitting = !(mConfig.get("TrackFitter:off", false)); + mDoTrackFitting = mConfig.get("TrackFitter:active", true); if (!mConfig.exists("TrackFitter")) mDoTrackFitting = false; - } - - - void writeEventHistograms() { - - // no file, dont write anything - if ( !gDirectory ) - return; + } //initialize - gDirectory->cd(); - // write out the config we use (do before histos): - TNamed n("mConfig", mConfig.dump()); - n.Write(); - - writeHistograms(); - - gDirectory->mkdir("Fit/"); - gDirectory->cd("Fit/"); - mTrackFitter->writeHistograms(); - gDirectory->cd(""); - mQualityPlotter->writeHistograms(); - } - - /** Loads Criteria from XML configuration. - * - * Utility function for loading criteria from XML config. - * - * @return vector of ICriterion pointers - */ + /** + * @brief Loads Criteria from XML configuration. + * Utility function for loading criteria from XML config. + * @param path : path in config to load + * @return vector of ICriterion pointers + */ std::vector loadCriteria(string path) { std::vector crits; @@ -252,10 +321,11 @@ class ForwardTrackMaker { float vmin = mConfig.get(p + ":min", 0); float vmax = mConfig.get(p + ":max", 1); - + KiTrack::ICriterion * crit = nullptr; if ( name == "Crit2_BDT" ){ - crit = new BDTCrit2( vmin, vmax ); + // crit = new BDTCrit2( vmin, vmax ); + LOG_WARN << "BDT Criteria not implemented/out of date" << endm; } else { crit = KiTrack::Criteria::createCriterion(name, vmin, vmax); } @@ -266,12 +336,32 @@ class ForwardTrackMaker { crits.push_back(new CriteriaKeeper(crit)); // CriteriaKeeper intercepts values and saves them else crits.push_back(crit); - + } return crits; + } // loadCriteria + + /** + * @brief Clear the loaded criteria + * @param crits : vector of ICriterion pointers to properly clear + */ + void clearCriteria( std::vector &crits ){ + for ( size_t i = 0; i < crits.size(); i++ ){ + if ( crits[i] ){ + delete crits[i]; + crits[i] = nullptr; + } + } + crits.clear(); } + /** + * @brief Get the Criteria Values object + * + * @param crit_name : Criteria to get + * @return std::vector : list of values + */ std::vector getCriteriaValues(std::string crit_name) { std::vector em; if (mSaveCriteriaValues != true) { @@ -293,8 +383,14 @@ class ForwardTrackMaker { } return em; - }; + } //getCriteriaValues + /** + * @brief Get the Criteria All Values object + * + * @param crit_name : Criteria values to get + * @return std::vector> : map of values + */ std::vector> getCriteriaAllValues(std::string crit_name) { std::vector> em; if (mSaveCriteriaValues != true) { @@ -316,8 +412,14 @@ class ForwardTrackMaker { } return em; - }; + } // getCriteriaAllValues + /** + * @brief Get the Criteria Track Ids object + * + * @param crit_name : Name of criteria to get track ids for + * @return std::vector : list of track ids + */ std::vector getCriteriaTrackIds(std::string crit_name) { std::vector em; if (mSaveCriteriaValues != true) { @@ -339,8 +441,12 @@ class ForwardTrackMaker { } return em; - }; + } //getCriteriaTrackIds + /** + * @brief Clear the saved values for two hit and three hit criteria + * + */ void clearSavedCriteriaValues() { if (mSaveCriteriaValues != true) { return; @@ -355,103 +461,28 @@ class ForwardTrackMaker { auto critKeeper = static_cast(crit); critKeeper->clear(); } - } + } // clearSavedCriteria + /** + * @brief Determine the total num of hits in the hitmap + * + * @param hitmap : hitmap to consider + * @return size_t : total num of hits + */ size_t nHitsInHitMap(FwdDataSource::HitMap_t &hitmap) { size_t n = 0; - for (auto kv : hitmap) { n += kv.second.size(); } - - return n; - } - - size_t countRecoTracks(size_t nHits) { - size_t n = 0; - - for (auto t : mRecoTracks) { - if (t.size() == nHits) - n++; - } - return n; } - void setupHistograms() { - - mHist["input_nhits"] = new TH1I("input_nhits", ";# hits", 1000, 0, 1000); - mHist["nAttemptedFits"] = new TH1I("nAttemptedFits", ";;# attempted fits", 10, 0, 10); - mHist["nPossibleFits"] = new TH1I("nPossibleFits", ";;# possible fits", 10, 0, 10); - // refit with silicon - mHist["nPossibleReFits"] = new TH1I("nPossibleReFits", ";;# possible REfits", 10, 0, 10); - mHist["nAttemptedReFits"] = new TH1I("nAttemptedReFits", ";;#attempted REfits", 10, 0, 10); - mHist["nFailedReFits"] = new TH1I("nFailedReFits", ";;# failed REfits", 10, 0, 10); - - mHist["FitStatus"] = new TH1I("FitStatus", ";;# failed REfits", 15, 0, 15); - FwdTrackerUtils::labelAxis(mHist["FitStatus"]->GetXaxis(), {"Seeds", "AttemptFit", "GoodFit", "BadFit", "GoodCardinal", "PossibleReFit", "AttemptReFit", "GoodReFit", "BadReFit", "w3Si","w2Si", "w1Si", "w0Si" }); - - mHist["FitDuration"] = new TH1I("FitDuration", ";Duration (ms)", 5000, 0, 50000); - mHist["nSiHitsFound"] = new TH2I( "nSiHitsFound", ";Si Disk; n Hits", 5, 0, 5, 10, 0, 10 ); - - mHist["Step1Duration"] = new TH1I("Step1Duration", ";Duration (ms)", 500, 0, 500); - mHist["Step2Duration"] = new TH1I("Step2Duration", ";Duration (ms)", 500, 0, 500); - mHist["Step3Duration"] = new TH1I("Step3Duration", ";Duration (ms)", 500, 0, 500); - mHist["Step4Duration"] = new TH1I("Step4Duration", ";Duration (ms)", 500, 0, 500); - } - - void fillHistograms() { - - if (mGenHistograms && mDataSource != nullptr) { - auto hm = mDataSource->getFttHits(); - for (auto hp : hm) - mHist["input_nhits"]->Fill(hp.second.size()); - } - } - - void writeHistograms() { - if ( !mGenHistograms ){ - return; - } - - for (auto nh : mHist) { - nh.second->SetDirectory(gDirectory); - nh.second->Write(); - } - } - - // this is the main event loop. doEvent processes a single event iEvent... - void make() { - - int single_event = mConfig.get("Input:event", -1); - - if (single_event >= 0) { - doEvent(single_event); - return; - } - - unsigned long long firstEvent = mConfig.get("Input:first-event", 0); - - if (mConfig.exists("Input:max-events")) { - unsigned long long maxEvents = mConfig.get("Input:max-events", 0); - - if (nEvents > maxEvents) - nEvents = maxEvents; - - } - - // loop over events - - for (unsigned long long iEvent = firstEvent; iEvent < firstEvent + nEvents; iEvent++) { - doEvent(iEvent); - } - - if (mGenHistograms){ - mQualityPlotter->finish(); - writeEventHistograms(); - } - } - + /** + * @brief Remove used hits from the hit map + * + * @param hitmap : hitmap with hits used this round + * @param tracks : tracks formed from hits + */ void removeHits(FwdDataSource::HitMap_t &hitmap, std::vector &tracks) { for (auto track : tracks) { @@ -469,290 +500,557 @@ class ForwardTrackMaker { } // loop on track } // removeHits - void doEvent(unsigned long long int iEvent = 0) { + + /** @brief merges the FST and FTT hitmaps into a single hitmap + * The FTT hits are shifted by the number of FST sectors + * @param hitmap1: FST hitmap + * @param hitmap2: FTT hitmap + * @return void + */ + void mergeHitmaps( FwdDataSource::HitMap_t &hitmap1, FwdDataSource::HitMap_t &hitmap2 ){ + static const int numFstSectors = 3; + for ( auto kv : hitmap2 ){ + for ( auto hit : kv.second ){ + dynamic_cast( hit )->setSector( hit->getSector() + numFstSectors ); + hitmap1[kv.first + numFstSectors].push_back( hit ); + } + } + } // mergeHitmaps + + /** @brief cleanup the event-wise data structures + * + */ + void cleanup() { /************** Cleanup ****************************************/ // Moved cleanup to the start of doEvent, so that the fit results // persist after the call - mRecoTracks.clear(); - mRecoTrackQuality.clear(); - mRecoTrackIdTruth.clear(); - mFitMoms.clear(); - mNumFstHits.clear(); - mFitStatus.clear(); - - - // Clear pointers to the track reps from previous event - for (auto p : mGlobalTrackReps) - delete p; - - mGlobalTrackReps.clear(); - - // Clear pointers to global tracks - for (auto p : mGlobalTracks) - delete p; - - mGlobalTracks.clear(); - + mTrackSeeds.clear(); mTrackResults.clear(); + mEventStats.reset(); + mTotalHitsRemoved = 0; /************** Cleanup **************************/ + } - if (mGenHistograms ){ - mQualityPlotter->startEvent(); // starts the timer for this event + bool useMcTrackFinding(){ + /*************************************************************/ + // Determine if we should use MC seed finding + /*************************************************************/ + bool mcTrackFinding = true; + if (mConfig.exists("TrackFinder")){ + mcTrackFinding = false; } + if (mConfig.exists("TrackFinder") && mConfig.get( "TrackFinder:mc", false ) == false ){ + mcTrackFinding = false; + } + if (mConfig.exists("TrackFinder") && mConfig.get( "TrackFinder:active", true ) == false){ + mcTrackFinding = true; + } + return mcTrackFinding; + } - mTotalHitsRemoved = 0; - + /** + * @brief Perform the track finding + * Creates a list of track seeds from the hitmaps + * Retrieve them using `getTrackSeeds()` + */ + void findTrackSeeds() { + cleanup(); /*************************************************************/ - // Step 1 - // Load and sort the hits + // Get the hitmaps /*************************************************************/ long long itStart = FwdTrackerUtils::nowNanoSecond(); - FwdDataSource::HitMap_t &hitmap = mDataSource->getFttHits();; + FwdDataSource::HitMap_t &fttHitmap = mDataSource->getFttHits(); + FwdDataSource::HitMap_t &fstHitmap = mDataSource->getFstHits(); + + /*************************************************************/ + // Determine seed finding mode + /*************************************************************/ + string hitmapSource = mConfig.get("TrackFinder:source", "ftt"); + LOG_INFO << "Hitmap Source: " << hitmapSource << endm; + mSeedSource = kSeqSeed; // default to FST + if (hitmapSource == "fst") + mSeedSource = kFstSeed; + else if (hitmapSource == "ftt") + mSeedSource = kFttSeed; + else if (hitmapSource == "seq") + mSeedSource = kSeqSeed; + else if (hitmapSource == "sim") + mSeedSource = kSimSeed; + LOG_INFO << "Performing Fwd Seed finding with mode: " << mConfig.get("TrackFinder:source", "ftt") << " = " << mSeedSource << endm; FwdDataSource::McTrackMap_t &mcTrackMap = mDataSource->getMcTracks(); - fillHistograms(); long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) - mHist["Step1Duration"]->Fill( duration ); - - - bool mcTrackFinding = true; - - if (mConfig.exists("TrackFinder")) - mcTrackFinding = false; - /***********************************************/ - // MC Track Finding - if (mcTrackFinding) { - LOG_DEBUG << "MC TRACK FINDING " << endm; - doMcTrackFinding(mcTrackMap); + mEventStats.mStep1Duration.push_back( duration ); - /***********************************************/ - // REFIT with Silicon hits - if (mConfig.get("TrackFitter:refitSi", true)) { - addSiHitsMc(); - } else { - LOG_DEBUG << "Skipping FST Hits" << endm; - // skip Si refit - } - /***********************************************/ - - if (mConfig.get("TrackFitter:refitGBL", true)) { - for (size_t i = 0; i < mGlobalTracks.size(); i++) { - mTrackFitter->refitTrackWithGBL(mGlobalTracks[i]); - } - } - - if (mGenHistograms ){ - mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus); - } + /*************************************************************/ + // DO MC Track Finding (if set to do so) + if (useMcTrackFinding()) { + doMcTrackFinding(mcTrackMap, mSeedSource); + mEventStats.mNumSeeds = mTrackSeeds.size(); + long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + mEventStats.mSeedFindingDuration.push_back( duration2 ); return; + } else { + LOG_DEBUG << "Performing Standard Track Finding" << endm; } - /***********************************************/ + /*************************************************************/ - /***********************************************/ + /*************************************************************/ // Standard Track Finding - // plus initial fit size_t nIterations = mConfig.get("TrackFinder:nIterations", 0); for (size_t iIteration = 0; iIteration < nIterations; iIteration++) { - doTrackIteration(iIteration, hitmap); - } - /***********************************************/ + if ( mSeedSource == kSimSeed){ + mergeHitmaps( fstHitmap, fttHitmap ); + } else { + if ( mSeedSource == kFstSeed || mSeedSource == kSeqSeed ){ + doSeedFindingIteration(iIteration, fstHitmap); + } + if ( mSeedSource == kFttSeed || mSeedSource == kSeqSeed){ + doSeedFindingIteration(iIteration, fttHitmap); + } + } + } // iIteration + /*************************************************************/ + mEventStats.mNumSeeds = mTrackSeeds.size(); + long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + mEventStats.mSeedFindingDuration.push_back( duration2 ); + } // FindTrackSeeds - /***********************************************/ - // REFIT with Silicon hits - if (mConfig.get("TrackFitter:refitSi", true)) { - addSiHits(); - } else { - // Skipping Si Refit + + std::vector< genfit::GFRaveVertex * > findFwdVertices( const vector &globalTracks ){ + // we will return a vector of vertices + std::vector< genfit::GFRaveVertex * > raveVertices; + + + // The RAVE factory needs the (bare) track pointers for vertex finding + vector tracks; + for ( auto gtr : globalTracks ){ + if ( gtr.mTrack ){ + tracks.push_back( gtr.mTrack.get() ); + } } - /***********************************************/ - if ( mGenHistograms ){ - mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus); + bool useBeamConstraint = false; + if ( useBeamConstraint ){ + // TODO: load "official" beamline constraint parameters + TMatrixDSym bscm(3); + const double bssXY = 2.0; + bscm(0, 0) = bssXY*bssXY; + bscm(1, 1) = bssXY*bssXY; + bscm(2, 2) = 50.5 * 50.5; + mGFRVertices.setBeamspot( TVector3( 0, 0, 0 ), bscm ); } - } // doEvent - void fitTrack(Seed_t &track) { - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("Seeds", 1); + + mGFRVertices.findVertices( &raveVertices, tracks, useBeamConstraint ); + LOG_DEBUG << "raveVertices.size() = " << raveVertices.size() << endm; + for ( auto vert : raveVertices ){ + LOG_DEBUG << TString::Format( "GFRaveVertex vertex @(%f, %f, %f)\n\n", vert->getPos().X(), vert->getPos().Y(), vert->getPos().Z() ) << endm; + LOG_DEBUG << "GFRaveVertex\n"; + // LOG_DEBUG << "Position: "; vert->getPos().Print(); + // LOG_DEBUG << "Covariance: "; vert->getCov().Print(); + LOG_DEBUG << "Ndf: " << vert->getNdf() << ", Chi2: " << vert->getChi2() << ", Id: " << vert->getId() << "\n"; + LOG_DEBUG << "Number of tracks: " << vert->getNTracks() << "\n"; } + // if there is no Event Vertex, then we will use the first vertex found + // if ( raveVertices.size() > 0 ){ + // mEventVertex = raveVertices[0]->getPos(); + // // mEventVertexHit.setPos( mEventVertex ); + // } - // Calculate the MC info first and check filters - int idt = 0; - double qual = 0; - idt = MCTruthUtils::dominantContribution(track, qual); - - - TVector3 mcSeedMom; + return raveVertices; + } - auto mctm = mDataSource->getMcTracks(); - // get the MC track momentum if we can - if (mctm.count(idt)) { - auto mct = mctm[idt]; - mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); + /** + * @brief Perform a single fit from seed points + * + * @param seed : seed points from either FTT or FST + * @param includeVertex : include the primary vertex in the fit or not + * @return GenfitTrackResult : result of the fit + */ + GenfitTrackResult fitTrack(Seed_t &seed, TVector3 *momentumSeedState = nullptr) { + LOG_DEBUG << "FwdTracker::fitTrack->" << endm; + mEventStats.mAttemptedFits++; + // We will build this up as we go + GenfitTrackResult gtr; + + LOG_DEBUG << "--Setting seed on GenfitTrackResult, seed has " << seed.size() << " hits" << endm; + // First, set the seed information + gtr.setSeed( seed ); + + // If we are using a provided momentum state + if ( momentumSeedState ){ + LOG_DEBUG << "--FitTrack with provided momentum seed state" << endm; + mTrackFitter->fitTrack( seed, momentumSeedState ); + } else { + LOG_DEBUG << "--FitTrack without provided momentum seed state" << endm; + mTrackFitter->fitTrack( seed ); } + /*******************************************************/ + // Get the track from the fitter + // and set the track in the GenfitTrackResult + if (mTrackFitter->getTrack() != nullptr ){ + LOG_DEBUG << "--FitTrack found, setting seed and track only" << endm; + gtr.set( seed, mTrackFitter->getTrack() ); - // Mc Filter - bool bailout = false; - if (qual < mConfig.get("TrackFitter.McFilter:quality-min", 0.0)) { - bailout = true; - // LOG_INFO << "BAIL OUT on Fit bc quality = " << qual << endm; - } - if (mctm.count(idt)) { - auto mct = mctm[idt]; - mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); - if (mct->mPt < mConfig.get("TrackFitter.McFilter:pt-min", 0.0) || - mct->mPt > mConfig.get("TrackFitter.McFilter:pt-max", 1e10)) { - bailout = true; - // LOG_INFO << "BAIL OUT on Fit bc Pt = " << mct->mPt << endm; - } - if (mct->mEta < mConfig.get("TrackFitter.McFilter:eta-min", 0) || - mct->mEta > mConfig.get("TrackFitter.McFilter:eta-max", 1e10)) { - bailout = true; - // LOG_INFO << "BAIL OUT on Fit bc eta = " << mct->mEta << endm; + if (gtr.mStatus && gtr.mStatus->isFitConvergedFully()) { + mEventStats.mGoodFits++; + } else { + mEventStats.mFailedFits++; } - - } else { - // cannot find the track + } else { // set the track as a failed fit, but keep the seed info + LOG_DEBUG << "--FitTrack failed, setting seed only" << endm; + mEventStats.mFailedFits++; } + LOG_DEBUG << "<-FwdTracker::fitTrack complete" << endm; + return gtr; + } // fitTrack - bailout = false; - - TVector3 p; - p.SetPtEtaPhi( 0, -999, 0 ); - genfit::FitStatus fitStatus; - - genfit::AbsTrackRep *trackRep = nullptr;//new genfit::RKTrackRep(211); // pdg for pi+ - genfit::Track *genTrack = nullptr;//new genfit::Track( trackRep, TVector3(0, 0, 0), TVector3(0, 0, 0) ); + + /** + * @brief Loop on track seeds and fit each one + * + * Track fitting proceeds in 3 possible iterations + * 1. Fit seed points (without PV) + * 2. Look for additional hits in the other tracking detector + * 3. Refit the track with the additional hits + * 4. Refit the track with the primary vertex + * 5. look again and refit any additional hits + * + * @param trackSeeds : Track seeds + */ + void doTrackFitting( const std::vector &trackSeeds) { + LOG_DEBUG << ">>doTrackFitting" << endm; + if (!mDoTrackFitting) + return; + long long itStart = FwdTrackerUtils::nowNanoSecond(); - if (mDoTrackFitting && !bailout) { - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("AttemptFit", 1); + std::vector globalTracks; + std::vector primaryTracks; + + // Should we try to refit the track with aadditional points from other detectors? + const bool doRefit = mConfig.get("TrackFitter:refit", false); + LOG_INFO << "TrackFitter:refit = " << doRefit << endm; + + // Should we use the MC momentum as a seed for the fit? + const bool useMcSeedMomentum = mConfig.get("TrackFitter:mcSeed", false); + LOG_INFO << "TrackFitter:mcSeed = " << useMcSeedMomentum << endm; + + LOG_DEBUG << "Starting track fitting loop, mTrackResults.size() = " << mTrackResults.size() << endm; + LOG_DEBUG << "Starting Track fitting loop on " << trackSeeds.size() << " track seeds" << endm; + size_t index = 0; + for (auto t : trackSeeds) { + + GenfitTrackResult gtrGlobalRefit; // will store refit if needed + LOG_DEBUG << "\tTrack seed initial global fit #" << index << endm; + /***********************************************************************************************************/ + // Tracking Step 1 + // Fit each accepted track seed + + // If we are using MC momentum get it from associated track + TVector3 momentumSeedStateMc; + TVector3 *pMomSeedState = nullptr; + int idt = 0; + double qual = 0; + // Get the quality and MC truth id + idt = MCTruthUtils::dominantContribution(t, qual); + LOG_INFO << "\t\tMc Match idTruth=" << idt << ", quality = " << qual << endm; + if (true == useMcSeedMomentum) { + /*******************************************************/ + // Only for Simulation + // Calculate the MC info first and check filters + + auto mctm = mDataSource->getMcTracks(); + // get the MC track momentum if we can (may be used for state seed) + if (mctm.count(idt)) { + auto mct = mctm[idt]; + momentumSeedStateMc.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); + // pMomSeedState = &momentumSeedStateMc; + } else { + LOG_WARN << "\tRequested MC momentum for fit seed, but couldnt find MC Track for id: " << idt << ", qual: " << qual << endm; + } + /*******************************************************/ + } // else if pMomSeedState = nullptr, a seed momentum will be computed from seed points by tracker + + // Fit the track seed and get the GenfitTrackResult + GenfitTrackResult gtrGlobal = fitTrack(t, pMomSeedState); + gtrGlobal.setDCA( mEventVertex ); + + LOG_DEBUG << "\tFit track seed with " << gtrGlobal.mSeed.size() << " hits" << endm; + LOG_DEBUG << "\t\t McTrack Id = " << gtrGlobal.mIdTruth << ", QA = " << gtrGlobal.mQaTruth << endm; + // End Step 1 + /*******************************************************/ + + + // if the first fit fails then we cannot proceed with the refit steps + if (gtrGlobal.mIsFitConvergedPartially == false) { + LOG_WARN << "\tInitial fitting failed for seed " << index << endm; + LOG_DEBUG << "\tFitting failed for seed " << index << endm; + LOG_DEBUG << "\tSkipping the refit steps but saving the seed and failed fit" << endm; + globalTracks.push_back( gtrGlobal ); + index++; + continue; + // BREAK OUT OF THE LOOP } - - double vertex[3] = { mEventVertex.X(), mEventVertex.Y(), mEventVertex.Z() }; - - double * pVertex = 0; - if ( fabs(mEventVertex.X()) < 100 ){ - pVertex = vertex; // only use it if it has been set from default + if (doRefit == false) { + LOG_INFO << "\tRefit is disabled, saving the seed and initial fit" << endm; + gtrGlobal.isPrimary = false; + globalTracks.push_back( gtrGlobal ); + index++; + continue; + // BREAK OUT OF THE LOOP } - - if (true == mConfig.get("TrackFitter:mcSeed", false)) { - // use the MC pt, eta, phi as the seed for fitting - p = mTrackFitter->fitTrack(track, pVertex, &mcSeedMom); + /***********************************************************************************************************/ + // Tracking Step 2 + // Look for additional hits in the other tracking detector + // and add the new hits to the track + + // If requested, use the MC track finding to add hits to the track + if (useMcTrackFinding()) { + if (mSeedSource != kFttSeed) addFttHitsMc( gtrGlobal ); + if (mSeedSource != kFstSeed) addFstHitsMc( gtrGlobal ); + // globalTracks.push_back( gtrGlobalRefit ); + // index++; + // continue; // below is for "real" track finding only, for MC jump to next track } else { - // Normal case, real data - p = mTrackFitter->fitTrack(track, pVertex); - } - - if ( mGenHistograms ){ - if (p.Perp() > 1e-3) { - mHist["FitStatus"]->Fill("GoodFit", 1); - } else { - mHist["FitStatus"]->Fill("BadFit", 1); + // If we are not using MC track finding, + // then we will look for additional hits via projections + if (mSeedSource != kFttSeed){ // Look for FTT hits if it was not the original seed source + for ( int i = 0; i < FwdSystem::sNFttLayers; i++ ){ + addFttHits( gtrGlobal, i ); + } + } + if (mSeedSource != kFstSeed ){ // Look for FST hits if it was not the original seed source + for ( int i = 0; i < FwdSystem::sNFstLayers; i++ ){ + addFstHits( gtrGlobal, i ); + } } + // global refit + } + // End Step 2 + /***********************************************************************************************************/ + + /***********************************************************************************************************/ + // Tracking Step 3: Fit the new global track with additional hits + gtrGlobalRefit = fitTrack( gtrGlobal.mSeed, >rGlobal.mMomentum ); + gtrGlobalRefit.setDCA( mEventVertex ); + // End Step 3 + /***********************************************************************************************************/ + + /***********************************************************************************************************/ + // Tracking Step 4: Save the best global track result + GenfitTrackResult *activeTrack = >rGlobal; + if ( gtrGlobalRefit.mIsFitConvergedPartially ){ + activeTrack = >rGlobalRefit; } - - genTrack = new genfit::Track(*mTrackFitter->getTrack()); - genTrack->setMcTrackId(idt); - GenfitTrackResult gtr( track.size(), 0, track, genTrack ); - - // assign the fit results to be saved - fitStatus = mTrackFitter->getStatus(); - trackRep = mTrackFitter->getTrackRep()->clone(); // Clone the track rep - - if ( mGenHistograms && genTrack->getFitStatus(genTrack->getCardinalRep())->isFitConverged() && p.Perp() > 1e-3) { - mHist["FitStatus"]->Fill("GoodCardinal", 1); + if ( !activeTrack->mIsFitConvergedPartially ){ + // should not be possible according to above logic... + LOG_WARN << "\tFWD global track fit failed (both initial + refit)" << endm; + continue; } - // Save everything (now use GenfitTrackResult) - mFitMoms.push_back(p); - mGlobalTracks.push_back(genTrack); - mGlobalTrackReps.push_back(trackRep); - mFitStatus.push_back(fitStatus); - mRecoTrackQuality.push_back(qual); - mRecoTrackIdTruth.push_back(idt); - mNumFstHits.push_back(0); - - mTrackResults.push_back( gtr ); - - LOG_DEBUG << "FwdTracker::fitTrack complete" << endm; - } // if (mDoTrackFitting && !bailout) - } + // if the refit is successful, + // then we will add the track to the globalTracks + // if not keep the original global track + activeTrack->isPrimary = false; // should be default but just make sure + globalTracks.push_back( *activeTrack ); // save this global track result + // End Step 4 + /***********************************************************************************************************/ + } // loop on track seeds + + long long duration1 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + mEventStats.mFitDuration.push_back( duration1 ); + float perGood = (float) mEventStats.mGoodFits / (float) mEventStats.mAttemptedFits; + float perFailed = (float) mEventStats.mFailedFits / (float) mEventStats.mAttemptedFits; + float perCardinals = (float) mEventStats.mGoodCardinals / (float) mEventStats.mGoodFits; + LOG_DEBUG << "\tGlobal Track Fitting Results:" << + TString::Format( + "Attempts = %d, Good = %d (%f%%), Failed = %d (%f%%), GoodCardinals = %d (%f%%)", + mEventStats.mAttemptedFits, + mEventStats.mGoodFits, + perGood, + mEventStats.mFailedFits, + perFailed, + mEventStats.mGoodCardinals, + perCardinals ) << endm; + + const bool do_fwd_vertex_finding = true; + if (do_fwd_vertex_finding){ + /***********************************************************************************************************/ + // Step 5: Find the FWD Vertices + LOG_DEBUG << "\tStarting Track Fitting Step 3 (FWD Vertex Finding)" << endm; + auto fwdVertices = findFwdVertices( globalTracks ); + mEventStats.mNumFwdVertices = fwdVertices.size(); + + for ( auto vert : fwdVertices ){ + LOG_DEBUG << "\tFound FWD Vertex @(" << vert->getPos().X() << ", " << vert->getPos().Y() << ", " << vert->getPos().Z() << ")" << endm; + LOG_DEBUG << "\t\tvs mEventVertexHit: " << mEventVertexHit.getX() << ", " << mEventVertexHit.getY() << ", " << mEventVertexHit.getZ() << endm; + } - void doTrackFitting( std::vector &tracks) { - long long itStart = FwdTrackerUtils::nowNanoSecond(); - // Fit each accepted track seed - for (auto t : tracks) { - fitTrack(t); - } - long long itEnd = FwdTrackerUtils::nowNanoSecond(); - long long duration = (itEnd - itStart) * 1e-6; // milliseconds - if ( mGenHistograms ){ - this->mHist["FitDuration"]->Fill(duration); + // End Step 5 + /***********************************************************************************************************/ + } else { + LOG_INFO << "Event configuration is skipping FWD vertex finding" << endm; } - // TODO: After tracking vertex finding... - } - void doMcTrackFinding(FwdDataSource::McTrackMap_t &mcTrackMap) { + const bool do_fwd_primary_fitting = true; + /***********************************************************************************************************/ + // Step 6: Refit the track with the primary vertex + index = 0; + if (do_fwd_primary_fitting){ + // Now try refitting every track with the primary vertex + for (auto >r : globalTracks) { + LOG_INFO << "Refitting Track " << index << ", McId=" << gtr.mIdTruth << " with Primary Vertex, seed already has: " << gtr.mSeed.size() << " hits" << endm; + LOG_INFO << "mEventVertexHit: " << mEventVertexHit.getX() << ", " << mEventVertexHit.getY() << ", " << mEventVertexHit.getZ() << endm; + // just use the global track to build the track that will use the PV also + Seed_t seedWithPV = gtr.mSeed; + seedWithPV.push_back( &mEventVertexHit ); + + // If we are using MC momentum get it from associated track + TVector3 momentumSeedStateMc; + TVector3 *pMomSeedState = >r.mMomentum; + // if (true == useMcSeedMomentum) { + // /*******************************************************/ + // // Only for Simulation + // // get the MC track momentum if we can (may be used for state seed) + // auto mctm = mDataSource->getMcTracks(); + // if (mctm.count(gtr.mIdTruth)) { + // auto mct = mctm[gtr.mIdTruth]; + // momentumSeedStateMc.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); + // pMomSeedState = &momentumSeedStateMc; + // LOG_INFO << "Setting momentum to MC Seed state value for primary refit" << endm; + // } else {} + // /*******************************************************/ + // } // else if pMomSeedState = nullptr, a seed momentum will be computed from seed points by tracker + + GenfitTrackResult gtrPV = fitTrack(seedWithPV, pMomSeedState); + if ( gtrPV.mIsFitConvergedFully ){ + mEventStats.mGoodPrimaryFits++; + } else { + mEventStats.mFailedPrimaryFits++; + continue; + } + gtrPV.setDCA( mEventVertex ); + gtrPV.isPrimary = true; + mEventStats.mAttemptedPrimaryFits ++; + primaryTracks.push_back( gtrPV ); + index++; + } + // End Step 6 + /***********************************************************************************************************/ + } else { + LOG_INFO << "Event configuration is skipping primary track fitting" << endm; + } - mQualityPlotter->startIteration(); + float perGoodPrim = (float) mEventStats.mGoodPrimaryFits / (float) mEventStats.mAttemptedPrimaryFits; + float perFailedPrim = (float) mEventStats.mFailedPrimaryFits / (float) mEventStats.mAttemptedPrimaryFits; + LOG_DEBUG << "\tPrimary Track Fitting Results:" << + TString::Format( + "Attempts = %d, Good = %d (%f%%), Failed = %d (%f%%)", + mEventStats.mAttemptedPrimaryFits, + mEventStats.mGoodPrimaryFits, + perGoodPrim, + mEventStats.mFailedPrimaryFits, + perFailedPrim + ) << endm; + + // Add the global and primary tracks to the results + LOG_DEBUG << "Ending track fitting loop, mTrackResults.size() = " << mTrackResults.size() << endm; + mTrackResults.insert( mTrackResults.end(), globalTracks.begin(), globalTracks.end() ); + LOG_DEBUG << "Copied globals, now mTrackResults.size() = " << mTrackResults.size() << endm; + mTrackResults.insert( mTrackResults.end(), primaryTracks.begin(), primaryTracks.end() ); + + long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + LOG_DEBUG << "Track fitting took " << duration2 << "ms" << endm; + LOG_DEBUG << "We fit " << globalTracks.size() << " global tracks and " << primaryTracks.size() << " primary tracks, total = " << mTrackResults.size() << endm; + } // doTrackFitting + + /** + * @brief MC track finding builds track seeds from available hits using MC association + * + * @param mcTrackMap : Mc tracks + * @param useFttAsSource : Use FTT for seeds or (false) use Fst + */ + void doMcTrackFinding(FwdDataSource::McTrackMap_t &mcTrackMap, int seedSource) { + LOG_INFO << "Running MC Seed Finding, mode: " << seedSource << endm; + // If we want sequential MC track finding then do them each individually + if ( seedSource == kSeqSeed ){ + doMcTrackFinding( mcTrackMap, kFstSeed ); + doMcTrackFinding( mcTrackMap, kFttSeed ); + return; + } + + mTrackSeedsThisIteration.clear(); // we will build reco tracks from each McTrack for (auto kv : mcTrackMap) { - + auto mc_track = kv.second; - if (mc_track->mHits.size() < 4){ // require min 4 hits on track + LOG_DEBUG << "McTrack[ " << kv.first << " ]: nFtt=" << mc_track->mFttHits.size() << ", nFst=" << mc_track->mFstHits.size() << endm; + + if (seedSource == kFttSeed && mc_track->mFttHits.size() < 2){ // require min 4 FTT hits on track + continue; + } + + if (seedSource == kFstSeed && mc_track->mFstHits.size() < 2 ) { // require min 3 FST hits on track + LOG_DEBUG << "Skipping McSeedFinding bc FST hits < 2" << endm; + continue; + } + + if ( seedSource == kSimSeed && mc_track->mFstHits.size() < 2 && mc_track->mFttHits.size() < 2 ){ continue; } std::set uvid; Seed_t track; - for (auto h : mc_track->mHits) { - track.push_back(h); - uvid.insert(static_cast(h)->_vid); + if ( seedSource != kFstSeed ){ // FTT is used unless we are ONLY considering FST + for (auto h : mc_track->mFttHits) { + track.push_back(h); + uvid.insert(static_cast(h)->_vid); + } + } + if (seedSource != kFttSeed ) { // FST + for (auto h : mc_track->mFstHits) { + track.push_back(h); + uvid.insert(static_cast(h)->_vid); + } } if (uvid.size() == track.size()) { // only add tracks that have one hit per volume - mRecoTracks.push_back(track); + mTrackSeedsThisIteration.push_back(track); int idt = 0; double qual = 0; idt = MCTruthUtils::dominantContribution(track, qual); - mRecoTrackQuality.push_back(qual); - mRecoTrackIdTruth.push_back(idt); } else { - //Skipping track that doesnt have hits on all layers + //Skipping track that doesnt have hits on all layers } } - LOG_DEBUG << "McTrackFinding Found: " << mRecoTracks.size() << " tracks" << endm; - - doTrackFitting(mRecoTracks); - - if ( mGenHistograms ){ - mQualityPlotter->afterIteration(0, mRecoTracks); - } - } + LOG_DEBUG << "McTrackFinding Found: " << mTrackSeedsThisIteration.size() << " tracks" << endm; + // doTrackFitting(mTrackSeedsThisIteration); + // Now save to the main reco track list + mTrackSeeds.insert( mTrackSeeds.end(), mTrackSeedsThisIteration.begin(), mTrackSeedsThisIteration.end() ); + } //doMcTrackFinding /** sliceHitMapInPhi * @brief Slices a hitmap into a phi section - * + * * @param inputMap INPUT hitmap to process * @param outputMap OUTPUT hitmap, will be cleared and filled with only the hits from inputMap that are within phi region * @param phi_min The minimum phi to accept * @param phi_max The maximum Phi to accept - * + * * @returns The number of hits in the outputMap */ size_t sliceHitMapInPhi( FwdDataSource::HitMap_t &inputMap, FwdDataSource::HitMap_t &outputMap, float phi_min, float phi_max ){ @@ -770,19 +1068,18 @@ class ForwardTrackMaker { } // loop on hits } // loop on map return n_hits_kept; - } + } // sliceHitMapInPhi - /** doTrackingOnHitmapSubset + /** doSeedFindingOnHitmapSubset * @brief Does track finding steps on a subset of hits (phi slice) * @param iIteration: tracking iteration (for determining params) * @param hitmap: the hitmap to use, should already be subset of original * @returns a list of track seeds */ - vector doTrackingOnHitmapSubset( size_t iIteration, FwdDataSource::HitMap_t &hitmap ) { + vector doSeedFindingOnHitmapSubset( size_t iIteration, FwdDataSource::HitMap_t &hitmap ) { long long itStart = FwdTrackerUtils::nowNanoSecond(); - std::vector acceptedTracks; - std::vector rejectedTracks; + std::vector acceptedTrackSeeds; /*************************************************************/ // Step 2 // build 2-hit segments (setup parent child relationships) @@ -800,7 +1097,7 @@ class ForwardTrackMaker { criteriaPath = "TrackFinder.SegmentBuilder"; } - mTwoHitCrit.clear(); + clearCriteria( mTwoHitCrit ); mTwoHitCrit = loadCriteria(criteriaPath); builder.addCriteria(mTwoHitCrit); @@ -811,19 +1108,22 @@ class ForwardTrackMaker { connPath = "TrackFinder.Connector"; unsigned int distance = mConfig.get(connPath + ":distance", 1); - + if (mSeedSource == kFttSeed){ + distance = 2; // set distance to 2 for FTT + } + FwdConnector connector(distance); builder.addSectorConnector(&connector); - + LOG_DEBUG << "Connector added: " << endm; // Get the segments and return an automaton object for further work - + KiTrack::Automaton automaton = builder.get1SegAutomaton(); LOG_DEBUG << TString::Format( "nSegments=%lu", automaton.getSegments().size() ).Data() << endm; LOG_DEBUG << TString::Format( "nConnections=%u", automaton.getNumberOfConnections() ).Data() << endm; - if (automaton.getNumberOfConnections() > 900 ){ + if (automaton.getNumberOfConnections() > 9000 ){ LOG_ERROR << "Got too many connections, bailing out of tracking" << endm; - return acceptedTracks; + return acceptedTrackSeeds; } // at any point we can get a list of tracks out like this: @@ -831,8 +1131,7 @@ class ForwardTrackMaker { // we can apply an optional parameter to only get tracks with >=nHits in them long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) - mHist["Step2Duration"]->Fill( duration ); + mEventStats.mStep2Duration.push_back(duration); itStart = FwdTrackerUtils::nowNanoSecond(); /*************************************************************/ @@ -846,35 +1145,20 @@ class ForwardTrackMaker { if (false == mConfig.exists(criteriaPath)) criteriaPath = "TrackFinder.ThreeHitSegments"; - mThreeHitCrit.clear(); + clearCriteria( mThreeHitCrit ); mThreeHitCrit = loadCriteria(criteriaPath); automaton.addCriteria(mThreeHitCrit); - automaton.lengthenSegments(); - - bool doAutomation = mConfig.get(criteriaPath + ":doAutomation", true); - bool doCleanBadStates = mConfig.get(criteriaPath + ":cleanBadStates", true); - - if (doAutomation) { - automaton.doAutomaton(); - } else { - //Not running Automation Step - } - - if (doAutomation && doCleanBadStates) { - automaton.cleanBadStates(); - } duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) - mHist["Step3Duration"]->Fill( duration ); - if (duration > 200 || automaton.getNumberOfConnections() > 900){ + mEventStats.mStep3Duration.push_back( duration ); + if (duration > 2000 || automaton.getNumberOfConnections() > 9000){ LOG_WARN << "The Three Hit Criteria took more than 200ms to process, duration: " << duration << " ms" << endm; LOG_WARN << "bailing out (skipping subset HNN)" << endm; - std::vector acceptedTracks; + std::string subsetPath = "TrackFinder.Iteration[" + std::to_string(iIteration) + "].SubsetNN"; size_t minHitsOnTrack = mConfig.get(subsetPath + ":min-hits-on-track", FwdSystem::sNFttLayers); - acceptedTracks = automaton.getTracks(minHitsOnTrack); - return acceptedTracks; + acceptedTrackSeeds = automaton.getTracks(minHitsOnTrack); + return acceptedTrackSeeds; } itStart = FwdTrackerUtils::nowNanoSecond(); @@ -915,46 +1199,48 @@ class ForwardTrackMaker { subset.calculateBestSet(comparer, quality); - acceptedTracks = subset.getAccepted(); + acceptedTrackSeeds = subset.getAccepted(); // this call takes a long time due to possible huge combinatorics. // rejectedTracks = subset.getRejected(); - // LOG_DEBUG << "We had " << tracks.size() << " tracks. Accepted = " << acceptedTracks.size() << ", Rejected = " << rejectedTracks.size() << endm; + // LOG_DEBUG << "We had " << tracks.size() << " tracks. Accepted = " << acceptedTrackSeeds.size() << ", Rejected = " << rejectedTracks.size() << endm; } else { // the subset and hit removal size_t minHitsOnTrack = mConfig.get(subsetPath + ":min-hits-on-track", FwdSystem::sNFttLayers); - acceptedTracks = automaton.getTracks(minHitsOnTrack); + acceptedTrackSeeds = automaton.getTracks(minHitsOnTrack); }// subset off duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) - mHist["Step4Duration"]->Fill( duration ); + mEventStats.mStep4Duration.push_back( duration ); if (duration > 500){ LOG_WARN << "The took more than 500ms to process, duration: " << duration << " ms" << endm; - LOG_WARN << "We got " << acceptedTracks.size() << " tracks this round" << endm; + LOG_WARN << "We got " << acceptedTrackSeeds.size() << " tracks this round" << endm; } - LOG_DEBUG << "We got " << acceptedTracks.size() << " tracks this round" << endm; - return acceptedTracks; - } // doTrackingOnHitmapSubset - - void doTrackIteration(size_t iIteration, FwdDataSource::HitMap_t &hitmap) { + LOG_DEBUG << "We got " << acceptedTrackSeeds.size() << " tracks this round" << endm; + return acceptedTrackSeeds; + } // doSeedFindingOnHitmapSubset + + /** + * @brief Main tracking procedure + * + * @param iIteration : The track iteration + * @param hitmap : the hitmap of available hits per plane + */ + void doSeedFindingIteration(size_t iIteration, FwdDataSource::HitMap_t &hitmap) { // empty the list of reco tracks for the iteration - mRecoTracksThisItertion.clear(); + mTrackSeedsThisIteration.clear(); // check to see if we have hits! size_t nHitsThisIteration = nHitsInHitMap(hitmap); - if (nHitsThisIteration < 4) { + const int minHitsToConsider = 3; + if (nHitsThisIteration < minHitsToConsider) { // No hits left in the hitmap! Skipping this iteration + LOG_INFO << "No hits to consider in this iteration, skipping" << endm; return; } - // this starts the timer for the iteration - if ( mGenHistograms ){ - mQualityPlotter->startIteration(); - } - std::string pslPath = "TrackFinder.Iteration["+ std::to_string(iIteration) + "]:nPhiSlices"; if ( false == mConfig.exists( pslPath ) ) pslPath = "TrackFinder:nPhiSlices"; size_t phi_slice_count = mConfig.get( pslPath, 1 ); @@ -964,12 +1250,12 @@ class ForwardTrackMaker { /*************************************************************/ // Steps 2 - 4 here /*************************************************************/ - auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, hitmap ); - mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() ); + auto acceptedTracks = doSeedFindingOnHitmapSubset( iIteration, hitmap ); + mTrackSeedsThisIteration.insert( mTrackSeedsThisIteration.end(), acceptedTracks.begin(), acceptedTracks.end() ); } else { FwdDataSource::HitMap_t slicedHitMap; - + if ( phi_slice_count == 0 || phi_slice_count > 100 ){ LOG_WARN << "Invalid phi_slice_count = " << phi_slice_count << ", resetting to 1" << endm; phi_slice_count= 1; @@ -979,31 +1265,32 @@ class ForwardTrackMaker { float phi_min = phi_slice_index * phi_slice - TMath::Pi(); float phi_max = (phi_slice_index + 1) * phi_slice - TMath::Pi(); + LOG_INFO << TString::Format( "phi slice = (%f, %f)", phi_min, phi_max ) << endm; /*************************************************************/ - // Step 1A + // Step 1 // Slice the hitmap into a phi section if needed // If we do that, check again that we arent wasting time on empty sections /*************************************************************/ size_t nHitsThisSlice = 0; if ( phi_slice_count > 1 ){ nHitsThisSlice = sliceHitMapInPhi( hitmap, slicedHitMap, phi_min, phi_max ); - if ( nHitsThisSlice < 4 ) { + if ( nHitsThisSlice < minHitsToConsider ) { continue; } } else { // no need to slice // I think this incurs a copy, maybe we can find a way to avoid. slicedHitMap = hitmap; } - + /*************************************************************/ // Steps 2 - 4 here /*************************************************************/ - auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, slicedHitMap ); - mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() ); + auto acceptedTracks = doSeedFindingOnHitmapSubset( iIteration, slicedHitMap ); + mTrackSeedsThisIteration.insert( mTrackSeedsThisIteration.end(), acceptedTracks.begin(), acceptedTracks.end() ); } //loop on phi slices }// if loop on phi slices - LOG_INFO << "."; + /*************************************************************/ // Step 5 // Remove the hits from any track that was found @@ -1012,188 +1299,164 @@ class ForwardTrackMaker { if ( false == mConfig.exists( hrmPath ) ) hrmPath = "TrackFinder.HitRemover"; if ( true == mConfig.get( hrmPath + ":active", true ) ){ - removeHits( hitmap, mRecoTracksThisItertion ); + removeHits( hitmap, mTrackSeedsThisIteration ); } - - LOG_DEBUG << " FITTING " << mRecoTracksThisItertion.size() << " now" << endm; - if ( mRecoTracksThisItertion.size() < 201 ){ - doTrackFitting( mRecoTracksThisItertion ); - } else { - LOG_ERROR << "BAILING OUT of fit, too many track candidates" << endm; - } - - if ( mGenHistograms ){ - mQualityPlotter->afterIteration( iIteration, mRecoTracksThisItertion ); - } - + LOG_DEBUG << " Found " << mTrackSeedsThisIteration.size() << " seed tracks this iteration" << endm; // Add the set of all accepted tracks (this iteration) to our collection of found tracks from all iterations - mRecoTracks.insert( mRecoTracks.end(), mRecoTracksThisItertion.begin(), mRecoTracksThisItertion.end() ); + mTrackSeeds.insert( mTrackSeeds.end(), mTrackSeedsThisIteration.begin(), mTrackSeedsThisIteration.end() ); + } // doSeedFindingIteration - } // doTrackIteration - - void addSiHitsMc() { + /** + * @brief Adds compatible FST hits to tracks seeded with FTT + * + */ + void addFstHitsMc( GenfitTrackResult >r ) { FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); - - for (size_t i = 0; i < mTrackResults.size(); i++) { - GenfitTrackResult >r = mTrackResults[i]; - - if ( gtr.status.isFitConverged() == false || gtr.momentum.Perp() < 1e-3) { - LOG_DEBUG << "Skipping addSiHitsMc, fit failed" << endm; - return; - } - - if ( mGenHistograms){ - mHist["FitStatus"]->Fill("PossibleReFit", 1); - } - - Seed_t si_hits_for_this_track(3, nullptr); - - for (size_t j = 0; j < 3; j++) { - for (auto h0 : hitmap[j]) { - if (dynamic_cast(h0)->_tid == gtr.track->getMcTrackId()) { - si_hits_for_this_track[j] = h0; - break; - } - } // loop on hits in this layer of hitmap - } // loop on hitmap layers - - size_t nSiHitsFound = 0; - if ( si_hits_for_this_track[0] != nullptr ) nSiHitsFound++; - if ( si_hits_for_this_track[1] != nullptr ) nSiHitsFound++; - if ( si_hits_for_this_track[2] != nullptr ) nSiHitsFound++; - LOG_DEBUG << "Found " << nSiHitsFound << " FST Hits on this track (MC lookup)" << endm; - - if ( mGenHistograms ){ - this->mHist[ "nSiHitsFound" ]->Fill( 1, ( si_hits_for_this_track[0] != nullptr ? 1 : 0 ) ); - this->mHist[ "nSiHitsFound" ]->Fill( 2, ( si_hits_for_this_track[1] != nullptr ? 1 : 0 ) ); - this->mHist[ "nSiHitsFound" ]->Fill( 3, ( si_hits_for_this_track[2] != nullptr ? 1 : 0 ) ); - } - - if (nSiHitsFound >= 1) { - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("AttemptReFit", 1); - } - TVector3 p = mTrackFitter->refitTrackWithSiHits(gtr.track, si_hits_for_this_track); - - if ( mGenHistograms ){ - if (p.Perp() == mFitMoms[i].Perp()) { - mHist["FitStatus"]->Fill("BadReFit", 1); - LOG_DEBUG << "refitTrackWithSiHits failed refit" << endm; - } else { - mHist["FitStatus"]->Fill("GoodReFit", 1); - gtr.setFst( si_hits_for_this_track, mTrackFitter->getTrack() ); - } + if ( gtr.mStatus->isFitConverged() == false || gtr.mMomentum.Perp() < 1e-3) { + LOG_DEBUG << "Skipping addFstHitsMc, fit failed" << endm; + return; + } + mEventStats.mPossibleReFit++; + Seed_t fstHitsThisTrack; + + for (size_t j = 0; j < 3; j++) { + for (auto h0 : hitmap[j]) { + if (dynamic_cast(h0)->_tid == gtr.mIdTruth) { + fstHitsThisTrack.push_back(h0); + break; } + } // loop on hits in this layer of hitmap + } // loop on hitmap layers + + LOG_DEBUG << "Found " << gtr.mSeed.size() << " existing seed points" << endm; + LOG_DEBUG << "Adding " << fstHitsThisTrack.size() << " new FST seed points" << endm; + + if (fstHitsThisTrack.size() >= 1) { + mEventStats.mAttemptedReFits++; + gtr.mSeed.insert( gtr.mSeed.end(), fstHitsThisTrack.begin(), fstHitsThisTrack.end() ); + } // we have 3 Si hits to refit with + } // addFstHitsMc + + /** + * @brief Adds compatible FTT hits to tracks seeded with FST + * + * @param gtr : The GenfitTrackResult to add FTT hits to + * @param disk : The FTT disk number + * @return Seed_t : The combined seed points + */ + void addFttHits( GenfitTrackResult >r, size_t disk ) { + FwdDataSource::HitMap_t hitmap = mDataSource->getFttHits(); + if ( disk > 3 ) { + LOG_WARN << "Invalid FTT disk number: " << disk << ", cannot add Ftt points to track" << endm; + return; + } + if (gtr.mIsFitConverged != true) + return; + mEventStats.mPossibleReFit++; - mNumFstHits[i] = nSiHitsFound; - mFitMoms[i] = p; - } // we have 3 Si hits to refit with - - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill( TString::Format( "w%luSi", nSiHitsFound ).Data(), 1 ); - } - - } // loop on the global tracks - } // ad Si hits via MC associations - - void addSiHits() { - FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); - - // loop on global tracks - for (size_t i = 0; i < mGlobalTracks.size(); i++) { - if (mGlobalTracks[i]->getFitStatus(mGlobalTracks[i]->getCardinalRep())->isFitConverged() == false) { - // Original Track fit did not converge, skipping - return; - } - - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("PossibleReFit", 1); - } - - Seed_t hits_near_disk0; - Seed_t hits_near_disk1; - Seed_t hits_near_disk2; - try { - auto msp2 = mTrackFitter->projectToFst(2, mGlobalTracks[i]); - auto msp1 = mTrackFitter->projectToFst(1, mGlobalTracks[i]); - auto msp0 = mTrackFitter->projectToFst(0, mGlobalTracks[i]); - - // now look for Si hits near these - hits_near_disk2 = findSiHitsNearMe(hitmap[2], msp2); - hits_near_disk1 = findSiHitsNearMe(hitmap[1], msp1); - hits_near_disk0 = findSiHitsNearMe(hitmap[0], msp0); - } catch (genfit::Exception &e) { - // Failed to project to Si disk: ", e.what() - } + Seed_t hits_near_plane; + try { + auto msp = mTrackFitter->projectToFtt(disk, gtr.mTrack); + + // now look for Ftt hits near the specified state + hits_near_plane = findFttHitsNearProjectedState(hitmap[disk], msp); + LOG_DEBUG << " Found #FTT hits on plane #" << disk << TString::Format( " = [%ld]", hits_near_plane.size() ) << endm; + } catch (genfit::Exception &e) { + // Failed to project + LOG_WARN << "Unable to get Ftt projections: " << e.what() << endm; + } - vector hits_to_add; + LOG_DEBUG << "Found " << gtr.mSeed.size() << " existing seed points" << endm; - size_t nSiHitsFound = 0; // this is really # of disks on which a hit is found + if ( hits_near_plane.size() > 0 ){ + mEventStats.mAttemptedReFits++; + LOG_DEBUG << "Adding " << hits_near_plane.size() << " new FTT seed points" << endm; + gtr.mSeed.insert( gtr.mSeed.end(), hits_near_plane.begin(), hits_near_plane.end() ); + } + return; + } // addFttHits - if ( mGenHistograms ){ - this->mHist[ "nSiHitsFound" ]->Fill( 1, hits_near_disk0.size() ); - this->mHist[ "nSiHitsFound" ]->Fill( 2, hits_near_disk1.size() ); - this->mHist[ "nSiHitsFound" ]->Fill( 3, hits_near_disk2.size() ); - } + /** + * @brief Adds compatible FTT hits using MC info + * + */ + void addFttHitsMc( GenfitTrackResult >r ) { + LOG_DEBUG << "Looking for FTT hits on this track (MC lookup)" << endm; + LOG_DEBUG << "Track TruthId = " << gtr.mIdTruth << " vs. " << gtr.mTrack->getMcTrackId() << endm; + FwdDataSource::HitMap_t hitmap = mDataSource->getFttHits(); + if ( gtr.mStatus->isFitConverged() == false || gtr.mMomentum.Perp() < 1e-6) { + LOG_DEBUG << "Skipping addFttHitsMc on this track, fit failed" << endm; + return; + } - // TODO: HANDLE multiple points found? - if ( hits_near_disk0.size() == 1 ) { - hits_to_add.push_back( hits_near_disk0[0] ); - nSiHitsFound++; - } else { - hits_to_add.push_back( nullptr ); - } - if ( hits_near_disk1.size() == 1 ) { - hits_to_add.push_back( hits_near_disk1[0] ); - nSiHitsFound++; - } else { - hits_to_add.push_back( nullptr ); - } - if ( hits_near_disk2.size() == 1 ) { - hits_to_add.push_back( hits_near_disk2[0] ); - nSiHitsFound++; - } else { - hits_to_add.push_back( nullptr ); - } + mEventStats.mPossibleReFit++; + Seed_t fttHitsForThisTrack; - if (nSiHitsFound >= 1) { - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("AttemptReFit", 1); - } - // LOG_INFO << "Fitting on GlobalTrack : " << mGlobalTracks[i] << " with " << nSiHitsFound << " si hits" << endm; - TVector3 p = mTrackFitter->refitTrackWithSiHits(mGlobalTracks[i], hits_to_add); - size_t lengthGTR = mTrackResults.size(); - if ( lengthGTR >= 1 ){ - mTrackResults[ lengthGTR - 1 ].setFst( hits_to_add, mTrackFitter->getTrack() ); - } else { - LOG_ERROR << "Fit Results not found" << endm; + for (size_t j = 0; j < 4; j++) { + for (auto h0 : hitmap[j]) { + if (dynamic_cast(h0)->_tid == gtr.mIdTruth) { + fttHitsForThisTrack.push_back( h0 ); + break; } + } // loop on hits in this layer of hitmap + } // loop on hitmap layers + + LOG_DEBUG << "Found " << fttHitsForThisTrack.size() << " FTT Hits on this track (MC lookup)" << endm; + + if (fttHitsForThisTrack.size() >= 1) { + mEventStats.mAttemptedReFits++; + gtr.mSeed.insert( gtr.mSeed.end(), fttHitsForThisTrack.begin(), fttHitsForThisTrack.end() ); + } // we have at least one Fst hit to refit with + } // add Ftt hits via MC associations + + /** + * @brief Adds compatible FST hits to a track + * + * @param gtr : The GenfitTrackResult to add FST hits to + * @param disk : The FST disk number + */ + void addFstHits( GenfitTrackResult >r, size_t disk ) { + FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); + if (gtr.mIsFitConverged == false) { + // Original Track fit did not converge, skipping + return; + } + if ( disk > 2 ){ + LOG_ERROR << "Invalid FST disk number: " << disk << endm; + return; + } + mEventStats.mPossibleReFit++; - if ( mGenHistograms ){ - if (p.Perp() == mFitMoms[i].Perp()) { - mHist["FitStatus"]->Fill("BadReFit", 1); - } else { - mHist["FitStatus"]->Fill("GoodReFit", 1); - } - } - - // mGlobalTracks[i] = mTrackFitter->getTrack(); - mNumFstHits[i] = nSiHitsFound; - mFitMoms[i] = p; - - } else { - // unable to refit - } - - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill( TString::Format( "w%luSi", nSiHitsFound ).Data(), 1 ); - } - - } // loop on globals - } // addSiHits + Seed_t nearby_hits; + try { + // get measured state on plane at specified disk + auto msp = mTrackFitter->projectToFst(disk, gtr.mTrack); + // now look for Si hits near this state + nearby_hits = findFstHitsNearProjectedState(hitmap[disk], msp); + } catch (genfit::Exception &e) { + LOG_WARN << "Unable to get projections: " << e.what() << endm; + } + LOG_DEBUG << "Track already has " << gtr.mSeed.size() << " existing seed points" << endm; - Seed_t findSiHitsNearMe(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dphi = 0.004 * 9.5, double dr = 2.75) { + if ( nearby_hits.size() > 0 ){ + mEventStats.mAttemptedReFits++; + LOG_DEBUG << "Adding " << nearby_hits.size() << " new FST seed points from disk " << disk << endm; + gtr.mSeed.insert( gtr.mSeed.end(), nearby_hits.begin(), nearby_hits.end() ); + } + return; + } // addFstHits + + /** + * @brief Finds FST hits near projected state + * + * @param available_hits : FST hits to consider + * @param msp : measured state on plabe from existing track projection + * @param dphi : search distance in phi + * @param dr : search distance in r + * @return Seed_t : compatible FST hits + */ + Seed_t findFstHitsNearProjectedState(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dphi = 0.004 * 20.5, double dr = 2.75 * 2) { double probe_phi = TMath::ATan2(msp.getPos().Y(), msp.getPos().X()); double probe_r = sqrt(pow(msp.getPos().X(), 2) + pow(msp.getPos().Y(), 2)); @@ -1203,51 +1466,109 @@ class ForwardTrackMaker { double h_phi = TMath::ATan2(h->getY(), h->getX()); double h_r = sqrt(pow(h->getX(), 2) + pow(h->getY(), 2)); double mdphi = fabs(h_phi - probe_phi); - + if (mdphi > 2*3.1415926) + mdphi = mdphi - 2*3.1415926; + if ( mdphi < dphi && fabs( h_r - probe_r ) < dr) { // handle 2pi edge found_hits.push_back(h); } } return found_hits; - } + } // findFstHitsNearProjectedState + + /** + * @brief Finds FTT hits near projected state + * + * @param available_hits : FTT hits to consider + * @param msp : measured state on plane from existing track fit projection + * @param dx : search distance in x + * @param dy : search distance in y + * + * @return compatible FTT hits + */ + Seed_t findFttHitsNearProjectedState(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dx = 1.5, double dy = 1.5) { + + Seed_t found_hits; + TLorentzVector lv1, lv2; + lv1.SetPxPyPzE( msp.getPos().X(), msp.getPos().Y(), 0, 1 ); + + double mindx = 99; + double mindy = 99; + double mindr = 99; + double mindp = 99; + KiTrack::IHit *closest = nullptr; + + for (auto h : available_hits) { + + lv2.SetPxPyPzE( h->getX(), h->getY(), 0, 1 ); + double sr = lv1.Pt() - lv2.Pt(); + double sp = lv1.DeltaPhi( lv2 ); + double sx = h->getX() - msp.getPos().X(); + double sy = h->getY() - msp.getPos().Y(); + + if ( fabs(sr) < fabs(mindr) ) + mindr = sr; + if ( fabs(sp) < fabs(mindp) ){ + mindp = sp; + closest = h; + } + if ( fabs(sx) < fabs(mindx) ) + mindx = sx; + if ( fabs(sy) < fabs(mindy) ) + mindy = sy; + + } // loop h + + if ( fabs(mindp) < 0.04*5 && fabs(mindr) < 9 ) { + found_hits.push_back(closest); + } + + return found_hits; + } // findFttHitsNearProjectedState bool getSaveCriteriaValues() { return mSaveCriteriaValues; } std::vector getTwoHitCriteria() { return mTwoHitCrit; } std::vector getThreeHitCriteria() { return mThreeHitCrit; } TrackFitter *getTrackFitter() { return mTrackFitter; } - void setEventVertex( TVector3 v ) { mEventVertex = v; } + void setEventVertex( TVector3 v, TMatrixDSym cov ){ + mEventVertex = v; + // this is the FwdHit we will use in seeds + mEventVertexHit.setXYZDetId( v.X(), v.Y(), v.Z(), kTpcId ); + for (size_t i=0; i < 3; i++){ + for (size_t j=0; j < 3; j++){ + mEventVertexHit._covmat(i,j) = cov(i,j); + } + } + } + TVector3 getEventVertex() { return mEventVertex; } protected: unsigned long long int nEvents; bool mDoTrackFitting = true; - bool mSaveCriteriaValues = true; + bool mSaveCriteriaValues = false; + enum SeedSource { kFstSeed = 0, kFttSeed, kSimSeed, kSeqSeed }; + int mSeedSource = 1; // 0 = FST, 1 = FTT, 2 = FST+FTT simultaneous, 3 = FST+FTT sequential FwdTrackerConfig mConfig; std::string mConfigFile; size_t mTotalHitsRemoved; - + std::vector mTrackResults; - std::vector mRecoTracks; // the tracks recod from all iterations - std::vector mRecoTracksThisItertion; + std::vector mTrackSeeds; // the tracks recod from all iterations + std::vector mTrackSeedsThisIteration; + + // Metrics about the event + EventStats mEventStats; // Set to the Primary vertex for the event TVector3 mEventVertex; - - // These are vectors with info about each track / fit - // they should all have the same length - std::vector mRecoTrackQuality; - std::vector mRecoTrackIdTruth; - std::vector mFitMoms; - std::vector mNumFstHits; - std::vector mFitStatus; - std::vector mGlobalTrackReps; - std::vector mGlobalTracks; - - QualityPlotter *mQualityPlotter; + FwdHit mEventVertexHit; + genfit::GFRaveVertexFactory mGFRVertices; + std::shared_ptr mDataSource; TrackFitter *mTrackFitter = nullptr; @@ -1256,12 +1577,7 @@ class ForwardTrackMaker { std::vector mThreeHitCrit; // histograms of the raw input data - bool mGenHistograms = false; // controls these histograms and use of QualityPlotter TString mGeoCache; - std::map mHist; - - - }; #endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h b/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h index 623b0172452..675881ccd50 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h @@ -1,4 +1,6 @@ +#ifndef __OBJEXPORTER_H__ +#define __OBJEXPORTER_H__ #include "GenFit/FitStatus.h" #include "GenFit/GFRaveVertexFactory.h" #include @@ -51,20 +53,20 @@ class ObjExporter { numVertices++; } } - + //## OUTPUT FACES BETWEEN INTERMEDIATE POINTS: - + for(p=1; pquadrant() == kFttQuadrantA ){ mx = 0; my = 0; sx = 1.0; sy = 1.0; @@ -249,13 +250,13 @@ class ObjExporter { } } } // ftt_strips - + // Output the event info into a useful format for event display - void output( std::string filename, + void output( std::string filename, StEvent * event, - std::vector< Seed_t> seeds, - std::vector< genfit::Track *> tracks, - const std::vector< genfit::GFRaveVertex *> &vertices, + std::vector< Seed_t> seeds, + std::vector< genfit::Track *> tracks, + const std::vector< genfit::GFRaveVertex *> &vertices, std::vector &fttHits, std::vector &fstHits, std::vector &fcsPreHits, // EPD = preshower @@ -306,9 +307,9 @@ class ObjExporter { ofile << "o fstHits" << endl; ofile << "usemtl fst_hits\n" << endl; for ( auto p : fstHits ){ - - float fstphi = TMath::ATan2( p.Y(), p.X() ); - printf( "FST PHI: %f \n", fstphi ); + + // float fstphi = TMath::ATan2( p.Y(), p.X() ); + // printf( "FST PHI: %f \n", fstphi ); // tri( ofile, TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.1f, 0.1f, 3.0f, fstphi ); sphere( TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.3, 10, 10, ofile ); } @@ -318,12 +319,12 @@ class ObjExporter { if (verbose){ LOG_INFO << "Viz has " << fcsPreHits.size() << " EPD Hits" << endm; } - if ( fcsPreHits.size() > 0 ){ + if ( fcsPreHits.size() > 0 ){ ofile << "\n" << endl; ofile << "o epd" << endl; ofile << "usemtl fcs_hits\n" << endl; for ( auto p : fcsPreHits ){ - + sphere( TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.25, 10, 10, ofile ); } } @@ -331,7 +332,7 @@ class ObjExporter { if (verbose){ LOG_INFO << "Viz has " << fcsClusters.size() << " FCS Hits" << endm; } - if ( fcsClusters.size() > 0 ){ + if ( fcsClusters.size() > 0 ){ ofile << "\n" << endl; ofile << "o fcs" << endl; ofile << "usemtl fcs_hits\n" << endl; @@ -343,7 +344,7 @@ class ObjExporter { i++; } } - + // Write the track seeds if (verbose){ LOG_INFO << "Viz has " << seeds.size() << " seeds" << endm; @@ -362,7 +363,7 @@ class ObjExporter { ofile << "l "; for ( size_t i = vStart; i < numVertices; i++){ - ofile << i+1 << " "; + ofile << i+1 << " "; } ofile << endl; } @@ -382,8 +383,8 @@ class ObjExporter { float zStep = 5.0; // cm for ( auto t : tracks ) { size_t vStart = numVertices; - - + + TVector3 lpoint; for ( float z = startPos.Z(); z < 875; z += zStep ){ TVector3 point = trackPosition( t, z ); @@ -393,18 +394,21 @@ class ObjExporter { vert( ofile, point.X() * SCALE, point.Y() * SCALE, -point.Z() * SCALE ); lpoint = point; } - + ofile << "l "; for ( size_t i = vStart; i < numVertices; i++){ - ofile << i+1 << " "; + ofile << i+1 << " "; } ofile << endl; } // for t in tracks } // if tracks.size() > 0 - ofile.close(); + ofile.close(); } size_t numVertices; }; + + +#endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h b/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h index de55a2a53e1..928a3e933ef 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h @@ -8,20 +8,6 @@ #include "GenFit/KalmanFitStatus.h" #include "GenFit/GblFitter.h" -#include "GenFit/KalmanFitter.h" -#include "GenFit/KalmanFitterInfo.h" -#include "GenFit/KalmanFitterRefTrack.h" -#include "GenFit/MaterialEffects.h" -#include "GenFit/PlanarMeasurement.h" -#include "GenFit/RKTrackRep.h" -#include "GenFit/SpacepointMeasurement.h" -#include "GenFit/StateOnPlane.h" -#include "GenFit/TGeoMaterialInterface.h" -#include "GenFit/Track.h" -#include "GenFit/TrackPoint.h" - -#include "Criteria/SimpleCircle.h" - #include "TDatabasePDG.h" #include "TGeoManager.h" #include "TMath.h" @@ -40,29 +26,35 @@ #include "StFwdTrackMaker/include/Tracker/FwdGeomUtils.h" #include "StarGenerator/UTIL/StarRandom.h" +#include "FitterUtils.h" -/* Cass for fitting tracks(space points) with GenFit +/* Class for interfacing with GenFit for fitting tracks * */ class TrackFitter { // Accessors and options public: - genfit::FitStatus getStatus() { return mFitStatus; } - genfit::AbsTrackRep *getTrackRep() { return mTrackRep; } - genfit::Track *getTrack() { return mFitTrack; } - void setGenerateHistograms( bool gen) { mGenHistograms = gen;} - + std::shared_ptr getTrack() { return mFitTrack; } public: - // ctor - // provide the main configuration object - TrackFitter(FwdTrackerConfig _mConfig, TString geoCache) : mConfig(_mConfig), mGeoCache(geoCache) { - mTrackRep = 0; - mFitTrack = 0; - } - + /** + * @brief Construct a new Track Fitter object + * + * @param _mConfig : Config object + * @param geoCache : Geometry cache filename + */ + TrackFitter(FwdTrackerConfig _mConfig, TString geoCache) : mConfig(_mConfig), mGeoCache(geoCache), mFitTrack(nullptr) {} + + /** + * @brief Setup the tracker object + * Load geometry + * Setup Material Effects + * Setup the magnetic field + * Setup the fitter + * Setup the fit planes + */ void setup() { // the geometry manager that GenFit will use @@ -77,56 +69,62 @@ class TrackFitter { // Set Material Stepper debug level genfit::MaterialEffects::getInstance()->setDebugLvl( mConfig.get("TrackFitter.MaterialEffects:DebugLvl", 0) ); - + genfit::MaterialEffects::getInstance()->setEnergyLossBetheBloch( mConfig.get("TrackFitter.MaterialEffects.EnergyLossBetheBloch", true) ); genfit::MaterialEffects::getInstance()->setNoiseBetheBloch( mConfig.get("TrackFitter.MaterialEffects.NoiseBetheBloch", true) ); genfit::MaterialEffects::getInstance()->setNoiseCoulomb( mConfig.get("TrackFitter.MaterialEffects.NoiseCoulomb", true) ); genfit::MaterialEffects::getInstance()->setEnergyLossBrems( mConfig.get("TrackFitter.MaterialEffects.EnergyLossBrems", true) ); genfit::MaterialEffects::getInstance()->setNoiseBrems( mConfig.get("TrackFitter.MaterialEffects.NoiseBrems", true) ); genfit::MaterialEffects::getInstance()->ignoreBoundariesBetweenEqualMaterials( mConfig.get("TrackFitter.MaterialEffects.ignoreBoundariesBetweenEqualMaterials", true) ); - + // do this last to override genfit::MaterialEffects::getInstance()->setNoEffects( !mConfig.get("TrackFitter:MaterialEffects", false)); // negated, true means defaul is all effects on (noEffects off) if (!mConfig.get("TrackFitter:MaterialEffects", false)){ LOG_INFO << "Turning OFF GenFit Material Effects in stepper" << endm; } - + // Determine which Magnetic field to use // Either constant field or real field from StarFieldAdaptor if (mConfig.get("TrackFitter:constB", false)) { - mBField = std::unique_ptr(new genfit::ConstField(0., 0., 5.)); // 0.5 T Bz - LOG_INFO << "StFwdTrackMaker: Tracking with constant magnetic field" << endl; + mBField = std::unique_ptr(new genfit::ConstField(0., 0., 5.0)); // 0.5 T Bz + LOG_INFO << "StFwdTrackMaker: Tracking with constant magnetic field" << endm; } else if (mConfig.get("TrackFitter:zeroB", false)) { mBField = std::unique_ptr(new genfit::ConstField(0., 0., 0.)); // ZERO FIELD - LOG_INFO << "StFwdTrackMaker: Tracking with ZERO magnetic field" << endl; + LOG_INFO << "StFwdTrackMaker: Tracking with ZERO magnetic field" << endm; } else { mBField = std::unique_ptr(new StarFieldAdaptor()); - LOG_INFO << "StFwdTrackMaker: Tracking with StarFieldAdapter" << endl; + LOG_INFO << "StFwdTrackMaker: Tracking with StarFieldAdapter" << endm; } // we must have one of the two available fields at this point // note, the pointer is still bound to the lifetime of the TackFitter - genfit::FieldManager::getInstance()->init(mBField.get()); + genfit::FieldManager::getInstance()->init(mBField.get()); // initialize the main mFitter using a KalmanFitter with reference tracks mFitter = std::unique_ptr(new genfit::KalmanFitterRefTrack()); - // Here we load several options from the config, + // Here we load several options from the config, // to customize the mFitter behavior mFitter->setMaxFailedHits(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxFailedHits", -1)); // default -1, no limit mFitter->setDebugLvl(mConfig.get("TrackFitter.KalmanFitterRefTrack:DebugLvl", 0)); // default 0, no output - mFitter->setMaxIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxIterations", 4)); // default 4 iterations + mFitter->setMaxIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxIterations", 40)); // default 4 iterations mFitter->setMinIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MinIterations", 0)); // default 0 iterations + // Set the fit convergence paramters + mFitter->setRelChi2Change( mConfig.get("TrackFitter.KalmanFitterRefTrack:RelChi2Change", 1e-3) ); + // mFitter->setAbsChi2Change( mConfig.get("TrackFitter.KalmanFitterRefTrack:AbsChi2Change", 1e-3) ); + mFitter->setDeltaPval( mConfig.get("TrackFitter.KalmanFitterRefTrack:DeltaPval", 1e-3) ); + mFitter->setBlowUpFactor( mConfig.get("TrackFitter.KalmanFitterRefTrack:BlowUpFactor", 1e3) ); + // FwdGeomUtils looks into the loaded geometry and gets detector z locations if present FwdGeomUtils fwdGeoUtils( gMan ); - // these default values are the default if the detector is - // a) not found in the geometry + // these default values are the default if the detector is + // a) not found in the geometry // b) not provided in config // NOTE: these defaults are needed since the geometry file might not include FST (bug being worked on separately) mFSTZLocations = fwdGeoUtils.fstZ( - mConfig.getVector("TrackFitter.Geometry:fst", + mConfig.getVector("TrackFitter.Geometry:fst", {140.286011, 154.286011, 168.286011 } // 144.633,158.204,171.271 ) @@ -184,7 +182,7 @@ class TrackFitter { LOG_DEBUG << sstr.str() << endm; // Now load FTT - // mConfig.getVector<>(...) requires a default, hence the + // mConfig.getVector<>(...) requires a default, hence the mFTTZLocations = fwdGeoUtils.fttZ( mConfig.getVector("TrackFitter.Geometry:ftt", {281.082,304.062,325.058,348.068}) ); @@ -212,242 +210,19 @@ class TrackFitter { delim = ", "; } LOG_DEBUG << sstr.str() << endm; - - // get default vertex values used in simulation from the config - mVertexSigmaXY = mConfig.get("TrackFitter.Vertex:sigmaXY", 1.0); - mVertexSigmaZ = mConfig.get("TrackFitter.Vertex:sigmaZ", 30.0); - mVertexPos = mConfig.getVector("TrackFitter.Vertex:pos", {0.0,0.0,0.0}); - mIncludeVertexInFit = mConfig.get("TrackFitter.Vertex:includeInFit", false); - - if ( mGenHistograms ) - makeHistograms(); - } - - void makeHistograms() { - std::string n = ""; - mHist["ECalProjPosXY"] = new TH2F("ECalProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); - mHist["ECalProjSigmaXY"] = new TH2F("ECalProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 50, 0, 0.5, 50, 0, 0.5); - mHist["ECalProjSigmaR"] = new TH1F("ECalProjSigmaR", ";#sigma_{XY} (cm) at ECAL", 50, 0, 0.5); - - mHist["SiProjPosXY"] = new TH2F("SiProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); - mHist["SiProjSigmaXY"] = new TH2F("SiProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 150, 0, 15, 150, 0, 15); - - mHist["VertexProjPosXY"] = new TH2F("VertexProjPosXY", ";X;Y", 100, -5, 5, 100, -5, 5); - mHist["VertexProjSigmaXY"] = new TH2F("VertexProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 150, 0, 20, 150, 0, 20); - - mHist["VertexProjPosZ"] = new TH1F("VertexProjPosZ", ";Z;", 100, -50, 50); - mHist["VertexProjSigmaZ"] = new TH1F("VertexProjSigmaZ", ";#sigma_{Z};", 100, 0, 10); - - mHist["SiWrongProjPosXY"] = new TH2F("SiWrongProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); - mHist["SiWrongProjSigmaXY"] = new TH2F("SiWrongProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 50, 0, 0.5, 50, 0, 0.5); - - mHist["SiDeltaProjPosXY"] = new TH2F("SiDeltaProjPosXY", ";X;Y", 1000, 0, 20, 1000, 0, 20); - - mHist["FstDiffZVsR"] = new TH2F( "FstDiffZVsR", ";R;dz", 400, 0, 40, 500, -5, 5 ); - mHist["FstDiffZVsPhiSliceInner"] = new TH2F( "FstDiffZVsPhiSliceInner", ";slice;dz", 15, 0, 15, 500, -5, 5 ); - mHist["FstDiffZVsPhiSliceOuter"] = new TH2F( "FstDiffZVsPhiSliceOuter", ";slice;dz", 15, 0, 15, 500, -5, 5 ); - - mHist["FstDiffZVsPhiOuter"] = new TH2F( "FstDiffZVsPhiOuter", ";slice;dz", 628, 0, TMath::Pi()*2, 500, -5, 5 ); - - mHist["CorrFstDiffZVsPhiSliceInner"] = new TH2F( "CorrFstDiffZVsPhiSliceInner", ";slice;dz", 15, 0, 15, 500, -5, 5 ); - mHist["CorrFstDiffZVsPhiSliceOuter"] = new TH2F( "CorrFstDiffZVsPhiSliceOuter", ";slice;dz", 15, 0, 15, 500, -5, 5 ); - - - n = "seed_curv"; - mHist[n] = new TH1F(n.c_str(), ";curv", 1000, 0, 10000); - n = "seed_pT"; - mHist[n] = new TH1F(n.c_str(), ";pT (GeV/c)", 500, 0, 10); - n = "seed_eta"; - mHist[n] = new TH1F(n.c_str(), ";eta", 500, 0, 5); - - n = "delta_fit_seed_pT"; - mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) pT (GeV/c)", 500, -5, 5); - n = "delta_fit_seed_eta"; - mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) eta", 500, 0, 5); - n = "delta_fit_seed_phi"; - mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) phi", 500, -5, 5); - - n = "FitStatus"; - mHist[n] = new TH1F(n.c_str(), ";", 5, 0, 5); - FwdTrackerUtils::labelAxis(mHist[n]->GetXaxis(), {"Total", "Pass", "Fail", "GoodCardinal", "Exception"}); - - n = "FitDuration"; - mHist[n] = new TH1F(n.c_str(), "; Duraton (ms)", 5000, 0, 50000); - - n = "FailedFitDuration"; - mHist[n] = new TH1F(n.c_str(), "; Duraton (ms)", 500, 0, 50000); - } - - // writes mHistograms stored in map only if mGenHistograms is true - void writeHistograms() { - if ( !mGenHistograms ) - return; - for (auto nh : mHist) { - nh.second->SetDirectory(gDirectory); - nh.second->Write(); - } } - /* Convert the 3x3 covmat to 2x2 by dropping z - * - */ - TMatrixDSym CovMatPlane(KiTrack::IHit *h){ - TMatrixDSym cm(2); - cm(0, 0) = static_cast(h)->_covmat(0, 0); - cm(1, 1) = static_cast(h)->_covmat(1, 1); - cm(0, 1) = static_cast(h)->_covmat(0, 1); - return cm; - } - - - /* FitSimpleCircle - * Used to determine a seed transverse momentum based on space points - * Takes a list of space points KiTrack::IHit * - * Takes three indecise used to lookup three of the possible hits within the list - */ - float fitSimpleCircle(Seed_t trackCand, size_t i0, size_t i1, size_t i2) { - float curv = 0; - - // ensure that no index is outside of range for FST or FTT volumes - if (i0 > 12 || i1 > 12 || i2 > 12) - return 0; - - try { - KiTrack::SimpleCircle sc(trackCand[i0]->getX(), trackCand[i0]->getY(), trackCand[i1]->getX(), trackCand[i1]->getY(), trackCand[i2]->getX(), trackCand[i2]->getY()); - curv = sc.getRadius(); - } catch (KiTrack::InvalidParameter &e) { - // if we got here we failed to get a valid seed. We will still try to move forward but the fit will probably fail - } - - // make sure the curv is valid - if (isinf(curv)) - curv = 999999.9; - - return curv; - } - - /* seedState - * Determines the seed position and momentum for a list of space points + /** + * @brief Get the Fst Plane object for a given hit + * + * @param h : hit + * @return genfit::SharedPlanePtr */ - float seedState(Seed_t trackCand, TVector3 &seedPos, TVector3 &seedMom) { - // we require at least 4 hits, so this should be gauranteed - if(trackCand.size() < 3){ - // failure - return 0.0; - } - - - // we want to use the LAST 3 hits, since silicon doesnt have R information - TVector3 p0, p1, p2; - // use the closest hit to the interaction point for the seed pos - FwdHit *hit_closest_to_IP = static_cast(trackCand[0]); - - // maps from to - std::map vol_map; - - // init the map - for (size_t i = 0; i < 13; i++) - vol_map[i] = -1; - - for (size_t i = 0; i < trackCand.size(); i++) { - auto fwdHit = static_cast(trackCand[i]); - vol_map[abs(fwdHit->_vid)] = i; - // find the hit closest to IP for the initial position seed - if (hit_closest_to_IP->getZ() > fwdHit->getZ()) - hit_closest_to_IP = fwdHit; - } - - // now get an estimate of the pT from several overlapping simple circle fits - // enumerate the available partitions - // 12 11 10 - // 12 11 9 - // 12 10 9 - // 11 10 9 - vector curvs; - curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[11], vol_map[10])); - curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[11], vol_map[9])); - curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[10], vol_map[9])); - curvs.push_back(fitSimpleCircle(trackCand, vol_map[11], vol_map[10], vol_map[9])); - - // average them and exclude failed fits - float mcurv = 0; - float nmeas = 0; - - for (size_t i = 0; i < curvs.size(); i++) { - if (mGenHistograms) - this->mHist["seed_curv"]->Fill(curvs[i]); - if (curvs[i] > 10) { - mcurv += curvs[i]; - nmeas += 1.0; - } - } - - if (nmeas >= 1) - mcurv = mcurv / nmeas; - else - mcurv = 10; - - // Now lets get eta information - // simpler, use farthest points from IP - if (vol_map[9] < 13) - p0.SetXYZ(trackCand[vol_map[9]]->getX(), trackCand[vol_map[9]]->getY(), trackCand[vol_map[9]]->getZ()); - - if (vol_map[10] < 13) - p1.SetXYZ(trackCand[vol_map[10]]->getX(), trackCand[vol_map[10]]->getY(), trackCand[vol_map[10]]->getZ()); - - const double K = 0.00029979; //K depends on the units used for Bfield - double pt = mcurv * K * 5; // pT from average measured curv - double dx = (p1.X() - p0.X()); - double dy = (p1.Y() - p0.Y()); - double dz = (p1.Z() - p0.Z()); - double phi = TMath::ATan2(dy, dx); - double Rxy = sqrt(dx * dx + dy * dy); - double theta = TMath::ATan2(Rxy, dz); - // double eta = -log( tantheta / 2.0 ); - // these starting conditions can probably be improvd, good study for student - - seedMom.SetPtThetaPhi(pt, theta, phi); - seedPos.SetXYZ(hit_closest_to_IP->getX(), hit_closest_to_IP->getY(), hit_closest_to_IP->getZ()); - - if (mGenHistograms) { - this->mHist["seed_pT"]->Fill(seedMom.Pt()); - this->mHist["seed_eta"]->Fill(seedMom.Eta()); - } - - return mcurv; - } - - - genfit::MeasuredStateOnPlane projectToFst(size_t si_plane, genfit::Track *fitTrack) { - if (si_plane > 2) { - genfit::MeasuredStateOnPlane nil; - return nil; - } - - auto detSi = mFSTPlanes[si_plane]; - genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); - auto TCM = fitTrack->getCardinalRep()->get6DCov(tst); - - // this returns the track length if needed - fitTrack->getCardinalRep()->extrapolateToPlane(tst, detSi); - - TCM = fitTrack->getCardinalRep()->get6DCov(tst); - - // can get the projected positions if needed - float x = tst.getPos().X(); - float y = tst.getPos().Y(); - float z = tst.getPos().Z(); - // and the uncertainties - LOG_DEBUG << "Track Uncertainty at FST (plane=" << si_plane << ") @ x= " << x << ", y= " << y << ", z= " << z << " : " << sqrt(TCM(0, 0)) << ", " << sqrt(TCM(1, 1)) << endm; - - return tst; - } - genfit::SharedPlanePtr getFstPlane( FwdHit * h ){ size_t planeId = h->getSector(); - TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); + const TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); double phi = hitXYZ.Phi(); if ( phi < 0 ) phi = TMath::Pi() * 2 + phi; @@ -467,477 +242,264 @@ class TrackFitter { } return planeCorr; + } // GetFST PLANE - } - - /* RefitTracksWithSiHits - * Takes a previously fit track re-fits it with the newly added silicon hits - * + /** + * @brief Convert the 3x3 covmat to 2x2 by dropping z + * + * @param h : hit with cov matrix + * @return TMatrixDSym : cov matrix 2x2 */ - TVector3 refitTrackWithSiHits(genfit::Track *originalTrack, Seed_t si_hits) { - // mem leak, global track is overwritten without delete. - TVector3 pOrig = originalTrack->getCardinalRep()->getMom(originalTrack->getFittedState(1, originalTrack->getCardinalRep())); - - // auto cardinalStatus = originalTrack->getFitStatus(originalTrack->getCardinalRep()); - - if (originalTrack->getFitStatus(originalTrack->getCardinalRep())->isFitConverged() == false) { - // in this case the original track did not converge so we should not refit. - // probably never get here due to previous checks - return pOrig; - } - - // Setup the Track Reps - auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); - auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); - - // get the space points on the original track - auto trackPoints = originalTrack->getPointsWithMeasurement(); - - if ((trackPoints.size() < (mFTTZLocations.size() +1) && mIncludeVertexInFit) || trackPoints.size() < mFTTZLocations.size() ) { - // we didnt get enough points for a refit - return pOrig; - } - - TVectorD rawCoords = trackPoints[0]->getRawMeasurement()->getRawHitCoords(); - double z = mFSTZLocations[0]; //first FTT plane, used if we dont have PV in fit - if (mIncludeVertexInFit) - z = rawCoords(2); - - TVector3 seedPos(rawCoords(0), rawCoords(1), z); - TVector3 seedMom = pOrig; - - // Create the ref track using the seed state - auto mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); - mFitTrack->addTrackRep(trackRepNeg); - - genfit::Track &fitTrack = *mFitTrack; - - size_t firstFTTIndex = 0; - if (mIncludeVertexInFit) { - // clone the PRIMARY VERTEX into this track - fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[0]->getRawMeasurement(), &fitTrack)); - firstFTTIndex = 1; // start on hit index 1 below - } - - // initialize the hit coords on plane - TVectorD hitCoords(2); - hitCoords[0] = 0; - hitCoords[1] = 0; - - size_t planeId(0); - int hitId(5); - - // add the hits to the track - for (auto h : si_hits) { - if ( nullptr == h ) continue; // if no Si hit in this plane, skip - - hitCoords[0] = h->getX(); - hitCoords[1] = h->getY(); - genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), h->getSector(), ++hitId, nullptr); - - planeId = h->getSector(); - - if (mFSTPlanes.size() <= planeId) { - LOG_WARN << "invalid VolumId -> out of bounds DetPlane, vid = " << planeId << endm; - return pOrig; - } - - // auto plane = mFSTPlanes[planeId]; - auto plane = getFstPlane( static_cast(h) ); - - measurement->setPlane(plane, planeId); - fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); - - - TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); - float phi = hitXYZ.Phi(); - if ( phi < 0 ) phi = TMath::Pi() * 2 + phi; - double phi_slice = phi / (TMath::Pi() / 6.0); // 2pi/12 - int phi_index = ((int)phi_slice); - double dz = (h->getZ() - plane->getO().Z()); - - double r =sqrt( pow(hitXYZ.x(), 2) + pow(hitXYZ.y(), 2) ); - - size_t idx = phi_index % 2; - auto planeCorr = mFSTPlanesInner[planeId + idx]; - if ( r > 16 ){ - planeCorr = mFSTPlanesOuter[planeId + idx]; - } - double cdz = (h->getZ() - planeCorr->getO().Z()); - - if (mGenHistograms){ - - ((TH2*)mHist[ "FstDiffZVsR" ])->Fill( r, dz ); - - if ( r < 16 ) {// inner - mHist["FstDiffZVsPhiSliceInner"]->Fill( phi_slice, dz ); - mHist["CorrFstDiffZVsPhiSliceInner"]->Fill( phi_slice, cdz ); - } else { - mHist["FstDiffZVsPhiSliceOuter"]->Fill( phi_slice, dz ); - mHist["CorrFstDiffZVsPhiSliceOuter"]->Fill( phi_slice, cdz ); - mHist["FstDiffZVsPhiOuter"]->Fill( phi, dz ); - } - } - // mHist[ "FstDiffZVsPhiSliceInner" ]->Fill( sqrt( pow(hitXYZ.x(), 2), pow(hitXYZ.y(), 2) ), dz ); - - } - // start at 0 if PV not included, 1 otherwise - for (size_t i = firstFTTIndex; i < trackPoints.size(); i++) { - // clone the track points into this track - fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[i]->getRawMeasurement(), &fitTrack)); - } - - try { - //Track RE-Fit with GENFIT2 - // check consistency of all points - fitTrack.checkConsistency(); - - // do the actual track fit - mFitter->processTrack(&fitTrack); - - fitTrack.checkConsistency(); - - // this chooses the lowest chi2 fit result as cardinal - fitTrack.determineCardinalRep(); - - } catch (genfit::Exception &e) { - // will be caught below by converge check - LOG_WARN << "Track fit exception : " << e.what() << endm; - } - - if (fitTrack.getFitStatus(fitTrack.getCardinalRep())->isFitConverged() == false) { - // Did not converge - return pOrig; - } else { // we did converge, return new momentum - - try { - // causes seg fault - auto cardinalRep = fitTrack.getCardinalRep(); - auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); - mFitStatus = *cardinalStatus; // save the status of last fit - } catch (genfit::Exception &e) { - } - - TVector3 p = fitTrack.getCardinalRep()->getMom(fitTrack.getFittedState(1, fitTrack.getCardinalRep())); - return p; - } - return pOrig; - } // refit with Si hits - - TVector3 refitTrackWithGBL( genfit::Track *originalTrack ) { - // mem leak, global track is overwritten without delete. - TVector3 pOrig = originalTrack->getCardinalRep()->getMom(originalTrack->getFittedState(1, originalTrack->getCardinalRep())); - - // auto cardinalStatus = originalTrack->getFitStatus(originalTrack->getCardinalRep()); - - if (originalTrack->getFitStatus(originalTrack->getCardinalRep())->isFitConverged() == false) { - // in this case the original track did not converge so we should not refit. - // probably never get here due to previous checks - return pOrig; - } - - // Setup the Track Reps - auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); - auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); - - // get the space points on the original track - auto trackPoints = originalTrack->getPointsWithMeasurement(); - - - TVectorD rawCoords = trackPoints[0]->getRawMeasurement()->getRawHitCoords(); - TVector3 seedPos(rawCoords(0), rawCoords(1), rawCoords(2)); - TVector3 seedMom = pOrig; - - // Create the ref track using the seed state - auto pFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); - pFitTrack->addTrackRep(trackRepNeg); - - genfit::Track &fitTrack = *pFitTrack; - - for (size_t i = 0; i < trackPoints.size(); i++) { - // clone the track points into this track - fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[i]->getRawMeasurement(), &fitTrack)); - } - - auto gblFitter = std::unique_ptr(new genfit::GblFitter()); - try { - // check consistency of all points - fitTrack.checkConsistency(); - - // do the actual track fit - mFitter->processTrack(&fitTrack); - - fitTrack.checkConsistency(); - - // this chooses the lowest chi2 fit result as cardinal - fitTrack.determineCardinalRep(); - - } catch (genfit::Exception &e) { - // will be caught below by converge check - LOG_WARN << "Track fit exception : " << e.what() << endm; - } - - if (fitTrack.getFitStatus(fitTrack.getCardinalRep())->isFitConverged() == false) { - LOG_WARN << "GBL fit did not converge" << endm; - delete pFitTrack; - return pOrig; - } else { // we did converge, return new momentum - - try { - // causes seg fault - auto cardinalRep = fitTrack.getCardinalRep(); - auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); - mFitStatus = *cardinalStatus; // save the status of last fit - } catch (genfit::Exception &e) { - LOG_WARN << "Failed to get cardinal status from converged fit" << endm; - } - auto mom = fitTrack.getCardinalRep()->getMom(fitTrack.getFittedState(1, fitTrack.getCardinalRep())); - delete pFitTrack; - return mom; - } - delete pFitTrack; - return pOrig; - } //refitwith GBL - + TMatrixDSym CovMatPlane(KiTrack::IHit *h){ + TMatrixDSym cm(2); + cm(0, 0) = static_cast(h)->_covmat(0, 0); + cm(1, 1) = static_cast(h)->_covmat(1, 1); + cm(0, 1) = static_cast(h)->_covmat(0, 1); + return cm; + } - /* Generic method for fitting space points with GenFit + /** + * @brief Get projection to given FST plane * - * + * @param fstPlane : plane index + * @param fitTrack : track to project + * @return genfit::MeasuredStateOnPlane */ - TVector3 fitSpacePoints( vector spoints, TVector3 &seedPos, TVector3 &seedMom ){ - - // setup track reps - auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); - auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); - - // setup track for fit with positive and negative reps - auto mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); - mFitTrack->addTrackRep(trackRepNeg); - - genfit::Track &fitTrack = *mFitTrack; - - // try adding the points to track and fitting - try { - for ( size_t i = 0; i < spoints.size(); i++ ){ - fitTrack.insertPoint(new genfit::TrackPoint(spoints[i], &fitTrack)); - } - // do the fit against the two possible fits - mFitter->processTrackWithRep(&fitTrack, trackRepPos); - mFitter->processTrackWithRep(&fitTrack, trackRepNeg); - - } catch (genfit::Exception &e) { - LOG_ERROR << "GenFit failed to fit track with: " << e.what() << endm; + genfit::MeasuredStateOnPlane projectToFst(size_t fstPlane, std::shared_ptr fitTrack) { + if (fstPlane > 2) { + genfit::MeasuredStateOnPlane nil; + return nil; } - try { - fitTrack.checkConsistency(); - - fitTrack.determineCardinalRep(); - auto cardinalRep = fitTrack.getCardinalRep(); + auto detFst = mFSTPlanes[fstPlane]; + // TODO: Why use 1 here? + genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); + // NOTE: this returns the track length if needed + fitTrack->getCardinalRep()->extrapolateToPlane(tst, detFst); - TVector3 p = cardinalRep->getMom(fitTrack.getFittedState(1, cardinalRep)); - // sucess, return momentum - return p; - } catch (genfit::Exception &e) { - LOG_ERROR << "GenFit failed to fit track with: " << e.what() << endm; - } - return TVector3(0, 0, 0); + return tst; } - /* Fit a track + /** + * @brief Get projection to given FTT plane * - * + * @param fttPlane : plane index + * @param fitTrack : track to project + * @return genfit::MeasuredStateOnPlane */ - TVector3 fitTrack(Seed_t trackCand, double *Vertex = 0, TVector3 *McSeedMom = 0) { - long long itStart = FwdTrackerUtils::nowNanoSecond(); - if (mGenHistograms) this->mHist["FitStatus"]->Fill("Total", 1); - - // The PV information, if we want to use it - TVectorD pv(3); - - StarRandom rand = StarRandom::Instance(); - if (0 == Vertex) { // randomized from simulation - pv[0] = mVertexPos[0] + rand.gauss(mVertexSigmaXY); - pv[1] = mVertexPos[1] + rand.gauss(mVertexSigmaXY); - pv[2] = mVertexPos[2] + rand.gauss(mVertexSigmaZ); - } else { - pv[0] = Vertex[0]; - pv[1] = Vertex[1]; - pv[2] = Vertex[2]; - } - - // get the seed info from our hits - TVector3 seedMom, seedPos; - // returns track curvature if needed - seedState(trackCand, seedPos, seedMom); - - if (McSeedMom != nullptr) { - seedMom = *McSeedMom; - } - - // If we use the PV, use that as the start pos for the track - if (mIncludeVertexInFit) { - LOG_DEBUG << "Primary Vertex in fit (seed pos) @ " << TString::Format( "(%f, %f, %f)", pv[0], pv[1], pv[2] ).Data() << endm; - seedPos.SetXYZ(pv[0], pv[1], pv[2]); + genfit::MeasuredStateOnPlane projectToFtt(size_t iFttPlane, std::shared_ptr fitTrack) { + if (iFttPlane > 3) { + genfit::MeasuredStateOnPlane nil; + return nil; } + auto fttPlane = mFTTPlanes[iFttPlane]; + // TODO: why use 1 here? + genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); + // NOTE: this returns the track length if needed + fitTrack->getCardinalRep()->extrapolateToPlane(tst, fttPlane); + return tst; + } - if (mFitTrack){ - delete mFitTrack; + /** + * @brief setup the track from the given seed and optional primary vertex + * @param trackSeed : seed points + * @param seedMom : seed momentum + * @param seedPos : seed position + * @param Vertex : primary vertex + */ + void setupTrack(Seed_t trackSeed ) { + + // setup the track fit seed parameters + GenericFitSeeder gfs; + int seedQ = 1; + TVector3 seedPos(0, 0, 0); + TVector3 seedMom(0, 0, 10); // this default seed actually works better than a half-bad guess + gfs.makeSeed( trackSeed, seedPos, seedMom, seedQ ); + LOG_DEBUG << "Setting track fit seed position = " << TString::Format( "(%f, %f, %f)", seedPos.X(), seedPos.Y(), seedPos.Z() ) << endm; + LOG_DEBUG << "Setting track fit seed momentum = " << TString::Format( "(%f, %f, %f)", seedMom.X(), seedMom.Y(), seedMom.Z() ) << endm; + if ( seedMom.Perp() > 0.001 ){ + // because ROOT has an assert in there :/ + LOG_DEBUG << "Setting track fit seed momentum = (Pt,eta,phi)=" << TString::Format( "(%f, %f, %f)", seedMom.Pt(), seedMom.Eta(), seedMom.Phi() ) << endm; } + + LOG_DEBUG << "Setting track fit seed charge = " << seedQ << endm; // create the track representations - auto trackRepPos = new genfit::RKTrackRep(mPdgMuon); - auto trackRepNeg = new genfit::RKTrackRep(mPdgAntiMuon); + // Note that multiple track reps differing only by charge results in a silent failure of GenFit + auto theTrackRep = new genfit::RKTrackRep(mPdgMuon * -1 * seedQ); // bc pos PDG codes are for neg particles // Create the track - mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); - mFitTrack->addTrackRep(trackRepNeg); - - - LOG_DEBUG - << "seedPos : (" << seedPos.X() << ", " << seedPos.Y() << ", " << seedPos.Z() << " )" - << ", seedMom : (" << seedMom.X() << ", " << seedMom.Y() << ", " << seedMom.Z() << " )" - << ", seedMom : (" << seedMom.Pt() << ", " << seedMom.Eta() << ", " << seedMom.Phi() << " )" - << endm; + mFitTrack = std::make_shared(theTrackRep, seedPos, seedMom); + // now add the points to the track - genfit::Track &fitTrack = *mFitTrack; - - size_t planeId(0); // detector plane ID int hitId(0); // hit ID + size_t planeId(0); // detector plane ID // initialize the hit coords on plane TVectorD hitCoords(2); hitCoords[0] = 0; hitCoords[1] = 0; - /****************************************************************************************************************** - * Include the Primary vertex if desired - ******************************************************************************************************************/ - if (mIncludeVertexInFit) { - - TMatrixDSym hitCov3(3); - hitCov3(0, 0) = mVertexSigmaXY * mVertexSigmaXY; - hitCov3(1, 1) = mVertexSigmaXY * mVertexSigmaXY; - hitCov3(2, 2) = mVertexSigmaZ * mVertexSigmaZ; - - genfit::SpacepointMeasurement *measurement = new genfit::SpacepointMeasurement(pv, hitCov3, 0, ++hitId, nullptr); - fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); - } - /****************************************************************************************************************** * loop over the hits, add them to the track ******************************************************************************************************************/ - for (auto h : trackCand) { - + // use these to enforce our sorting parameters + size_t idxFst = 0; // index of the FST hit + size_t idxFtt = 0; // index of the FTT hit + for (auto h : trackSeed) { + auto fh = dynamic_cast(h); hitCoords[0] = h->getX(); hitCoords[1] = h->getY(); - - genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), h->getSector(), ++hitId, nullptr); - planeId = h->getSector(); + /****************************************************************************************************************** + * If the Primary vertex is included + ******************************************************************************************************************/ + if ( true ) { + LOG_INFO << "Treating hit as a spacepoint" << endm; + if ( fh->isPV() ){ + LOG_DEBUG << "Including primary vertex in fit" << endm; + } + TVectorD pv(3); + pv[0] = h->getX(); + pv[1] = h->getY(); + pv[2] = h->getZ(); + LOG_INFO << "x = " << pv[0] << "+/- " << fh->_covmat(0,0) << ", y = " << pv[1] << " +/- " << fh->_covmat(1,1) << ", z = " << pv[2] << " +/- " << fh->_covmat(2,2) << endm; + auto tp = new genfit::TrackPoint(); + genfit::SpacepointMeasurement *measurement = new genfit::SpacepointMeasurement(pv, fh->_covmat, fh->_detid, ++hitId, tp); + tp->addRawMeasurement(measurement); + tp->setTrack(mFitTrack.get()); + if ( fh->isPV() ){ + tp->setSortingParameter(0); + } + if ( fh->isFtt() ){ + tp->setSortingParameter(4 + idxFtt); + idxFtt++; + } + if ( fh->isFst() ){ + tp->setSortingParameter(1 + idxFst); + idxFst++; + } + + mFitTrack->insertPoint( tp ); + continue; + } + + // if ( fh->isPV() ) continue; - if (mFTTPlanes.size() <= planeId) { - LOG_WARN << "invalid VolumId -> out of bounds DetPlane, vid = " << planeId << endm; - return TVector3(0, 0, 0); + genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), fh->_detid, ++hitId, nullptr); + + planeId = h->getSector(); + genfit::SharedPlanePtr plane; + if ( fh->isFtt() ){ + planeId = fh->_vid - 9; } + LOG_INFO << "planeId = " << planeId << ", sector " << h->getSector() << ", vid = " << fh->_vid << endm; + if (fh->isFtt() && mFTTPlanes.size() <= planeId) { + LOG_ERROR << "invalid VolumId -> out of bounds DetPlane, vid = " << dynamic_cast(h)->_vid << " vs. planeId = " << planeId << endm; + delete measurement; + continue; + } + + if (fh->isFtt()) + plane = mFTTPlanes[planeId]; + else if (fh->isFst()) + plane = getFstPlane( fh ); - auto plane = mFTTPlanes[planeId]; measurement->setPlane(plane, planeId); - fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); + + mFitTrack->insertPoint(new genfit::TrackPoint(measurement, mFitTrack.get())); + LOG_INFO << "\tsetupTrack: Hit at Z = " << h->getZ() << " with plane at Z = " << plane->getO().Z() << endm; if (abs(h->getZ() - plane->getO().Z()) > 0.05) { LOG_WARN << "Z Mismatch h->z = " << h->getZ() << ", plane->z = "<< plane->getO().Z() <<", diff = " << abs(h->getZ() - plane->getO().Z()) << endm; } - } // loop on trackCand - + } // loop on trackSeed + } // setupTrack + /** @brief performs the fit on a track + * @param t : track to fit + */ + void performFit( std::shared_ptr t ){ /****************************************************************************************************************** * Do the fit ******************************************************************************************************************/ try { - // do the fit - mFitter->processTrackWithRep(&fitTrack, trackRepPos); - mFitter->processTrackWithRep(&fitTrack, trackRepNeg); - } catch (genfit::Exception &e) { - if (mGenHistograms) mHist["FitStatus"]->Fill("Exception", 1); - } + // prepare the track for fitting + // int nFailedPoints = 0; + // bool changed = false; + // changed = dynamic_cast( mFitter.get() )->prepareTrack( mFitTrack.get(), mFitTrack->getCardinalRep(), false, nFailedPoints); + // LOG_DEBUG << "Track prepared for fit with " << nFailedPoints << " failed points, changed? = " << changed << endm; - TVector3 p(0, 0, 0); + // check the track for consistency + mFitTrack->checkConsistency(); + // do the fit + mFitter->processTrack(t.get()); - /****************************************************************************************************************** - * Now check the fit - ******************************************************************************************************************/ - try { - //check - fitTrack.checkConsistency(); + // check the track for consistency + t->checkConsistency(); // find track rep with smallest chi2 - fitTrack.determineCardinalRep(); - auto cardinalRep = fitTrack.getCardinalRep(); - auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); - mFitStatus = *cardinalStatus; // save the status of last fit - - // Delete any previous track rep - if (mTrackRep) - delete mTrackRep; - - // Clone the cardinal rep for persistency - mTrackRep = cardinalRep->clone(); // save the result of the fit - if (fitTrack.getFitStatus(cardinalRep)->isFitConverged() && mGenHistograms ) { - this->mHist["FitStatus"]->Fill("GoodCardinal", 1); + t->determineCardinalRep(); + // update the seed + // t->udpateSeed(); + + auto status = t->getFitStatus(); + LOG_INFO << "Fit status: " << status->isFitConverged() << endm; + LOG_INFO << "-Fit pvalue: " << status->getPVal() << endm; + LOG_INFO << "-Fit Chi2: " << status->getChi2() << endm; + + if ( status->isFitConverged() ){ + + auto cr = t->getCardinalRep(); + auto p = cr->getMom( t->getFittedState( 0, cr )); + int rcQ = status->getCharge(); + LOG_INFO << "Fit momentum: " << p.X() << ", " << p.Y() << ", " << p.Z() << endm; + LOG_INFO << "\tFit Pt: " << p.Pt() << ", eta: " << p.Eta() << ", phi: " << p.Phi() << endm; + // LOG_INFO << "\tMc Pt: " << mcMom.Pt() << ", eta: " << mcMom.Eta() << ", phi: " << mcMom.Phi() << endm; } - if (fitTrack.getFitStatus(trackRepPos)->isFitConverged() == false && - fitTrack.getFitStatus(trackRepNeg)->isFitConverged() == false) { - - LOG_WARN << "FWD Track GenFit Failed" << endm; - - p.SetXYZ(0, 0, 0); - long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) { - this->mHist["FitStatus"]->Fill("Fail", 1); - this->mHist["FailedFitDuration"]->Fill(duration); - } - return p; - } // neither track rep converged - - p = cardinalRep->getMom(fitTrack.getFittedState(1, cardinalRep)); - mQ = cardinalRep->getCharge(fitTrack.getFittedState(1, cardinalRep)); - mP = p; - - LOG_DEBUG << "track fit p = " << TString::Format( "(%f, %f, %f), q=%f", p.X(), p.Y(), p.Z(), mQ ).Data() << endm; } catch (genfit::Exception &e) { - LOG_WARN << "Exception on track fit: " << e.what() << endm; - p.SetXYZ(0, 0, 0); - - long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) { - this->mHist["FitStatus"]->Fill("Exception", 1); - this->mHist["FailedFitDuration"]->Fill(duration); - } - - return p; - } // try/catch - - long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) { - this->mHist["FitStatus"]->Fill("Pass", 1); - this->mHist["delta_fit_seed_pT"]->Fill(p.Pt() - seedMom.Pt()); - this->mHist["delta_fit_seed_eta"]->Fill(p.Eta() - seedMom.Eta()); - this->mHist["delta_fit_seed_phi"]->Fill(p.Phi() - seedMom.Phi()); - this->mHist["FitDuration"]->Fill(duration); + LOG_ERROR << "Exception on fit update" << e.what() << endm; } - return p; + LOG_INFO << "Track fit update complete!" << endm; } - int getCharge() { - return (int)mQ; - } + /** + * @brief Primary track fitting routine + * + * @param trackSeed : + * @param Vertex : Primary Vertex + * @param seedMomentum : seed momentum (can be from MC) + * @return void : the results can be accessed via the getTrack() method + */ + long long fitTrack(Seed_t trackSeed, TVector3 *seedMomentum = 0) { + long long itStart = FwdTrackerUtils::nowNanoSecond(); + LOG_DEBUG << "Fitting track with " << trackSeed.size() << " FWD Measurements" << endm; + + /****************************************************************************************************************** + * First sort the seed, bc GENFIT seemingly cannot handle out of order points + ******************************************************************************************************************/ + std::sort(trackSeed.begin(), trackSeed.end(), + [](KiTrack::IHit *a, KiTrack::IHit *b) + { return a->getZ() < b->getZ(); } + ); + + /****************************************************************************************************************** + * Setup the track fit seed parameters and objects + ******************************************************************************************************************/ + setupTrack(trackSeed); + LOG_DEBUG << "Ready to fit with " << mFitTrack->getNumPoints() << " track points" << endm; - + /****************************************************************************************************************** + * Do the fit + ******************************************************************************************************************/ + performFit( mFitTrack ); + long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + return duration; + } // fitTrack // Store the planes for FTT and FST vector mFTTPlanes; @@ -945,18 +507,12 @@ class TrackFitter { vector mFSTPlanesInner; vector mFSTPlanesOuter; - void SetIncludeVertex( bool vert ) { mIncludeVertexInFit = vert; } - protected: std::unique_ptr mBField; FwdTrackerConfig mConfig; // main config object TString mGeoCache; - // optional histograms, off by default - std::map mHist; - bool mGenHistograms = false; - // Main GenFit fitter instance std::unique_ptr mFitter = nullptr; @@ -972,20 +528,8 @@ class TrackFitter { // det z locations loaded from geom or config vector mFSTZLocations, mFTTZLocations; - // parameter ALIASED from mConfig wrt PV vertex - double mVertexSigmaXY = 1; - double mVertexSigmaZ = 30; - vector mVertexPos; - bool mIncludeVertexInFit = false; - - // GenFit state - genfit::FitStatus mFitStatus; - genfit::AbsTrackRep *mTrackRep; - genfit::Track *mFitTrack; - - // Fit results - TVector3 mP; - double mQ; + // GenFit state - resused + std::shared_ptr mFitTrack; }; #endif diff --git a/StRoot/StFwdTrackMaker/macro/build_geom.C b/StRoot/StFwdTrackMaker/macro/build_geom.C index f0fd5663882..327c9af71eb 100755 --- a/StRoot/StFwdTrackMaker/macro/build_geom.C +++ b/StRoot/StFwdTrackMaker/macro/build_geom.C @@ -2,7 +2,7 @@ // that is a valid shebang to run script as executable -void build_geom( TString geomtag = "dev2022", TString output="fGeom.root" ) { +void build_geom( TString geomtag = "y2023", TString output="fGeom.root" ) { gSystem->Load( "libStarRoot.so" ); @@ -21,7 +21,8 @@ void build_geom( TString geomtag = "dev2022", TString output="fGeom.root" ) { if ( 0 == geom ) { AgModule::SetStacker( new StarTGeoStacker() ); AgPosition::SetDebug(2); - StarGeometry::Construct("dev2022"); + cout << "Building geometry for tag [" << geomtag.Data() << "]" << endl; + StarGeometry::Construct( geomtag.Data() ); // Genfit requires the geometry is cached in a ROOT file gGeoManager->Export( output.Data() ); diff --git a/StRoot/StFwdTrackMaker/macro/daq/daq_track.C b/StRoot/StFwdTrackMaker/macro/daq/daq_track.C index 785b91ecbf5..c4bae46af5b 100755 --- a/StRoot/StFwdTrackMaker/macro/daq/daq_track.C +++ b/StRoot/StFwdTrackMaker/macro/daq/daq_track.C @@ -1,42 +1,79 @@ //usr/bin/env root4star -l -b -q $0; exit $? // that is a valid shebang to run script as executable -void daq_track( int n = 10, - const char *inFile = "input.daq", - std::string configFile = "daq/daq_track.xml", - const char *geom = "dev2022") { + +void daq_track( int n = 50, + const char *inFile = "st_fwd_23074018_raw_1000013.daq", + const char *geom = "y2023") { TString _chain; gSystem->Load( "libStarRoot.so" ); // Simplest chain with fst, fcs, ftt and fwdTracker - _chain = Form("in, %s, db, StEvent, MuDST, fcs, fst, ftt, fwdTrack", geom); - - // needed in this wonky spack environment + _chain = Form("in, %s, db, StEvent, trgd, btof, fcs, fst, ftt, fwdTrack, fstMuRawHit, EventQA, CMuDst, evout, tree", geom); + // _chain = Form("in, %s, StEvent, fcs, fst, ftt, fwdTrack, evout, tree", geom); + + // needed in this wonky spack environment / docker container gROOT->SetMacroPath(".:/star-sw/StRoot/macros:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); gROOT->LoadMacro("bfc.C"); bfc(-1, _chain, inFile); - // Extra configuration for the Forward Tracking - StFwdTrackMaker *fwdTrack = (StFwdTrackMaker*) chain->GetMaker("fwdTrack"); - if ( fwdTrack ){ //if it is in the chain - fwdTrack->SetConfigFile( configFile ); - // write debug histograms and ttree? - fwdTrack->SetGenerateTree( true ); - fwdTrack->SetGenerateHistograms( true ); - // write out wavefront OBJ files - fwdTrack->SetVisualize( false ); + + StFttClusterMaker *fttClu = (StFttClusterMaker*) chain->GetMaker("stgcCluster"); + if (fttClu){ + // fttClu->SetDebug(2); + fttClu->SetTimeCut( 1, -40, 40); + } + + StMaker * fwdMakerGen = chain->GetMaker("fwdTrack"); + if ( fwdMakerGen ){ + // Extra configuration for the Forward Tracking + StFwdTrackMaker *fwdTrack = (StFwdTrackMaker*) chain->GetMaker("fwdTrack"); + if ( fwdTrack ){ //if it is in the chain + cout << "Setting up Fwd Tracking in chain" << endl; + // fwdTrack->SetConfigFile( configFile ); + fwdTrack->setConfigForData(); + fwdTrack->setZeroB(); + fwdTrack->setSeedFindingWithFst(); + // write out wavefront OBJ files + fwdTrack->SetVisualize( false ); + fwdTrack->SetDebug(2); + fwdTrack->setTrackRefit(true); + fwdTrack->setGeoCache( "fGeom.root" ); + // fwdTrack->setDebug(); + + + } } + // The PicoDst + gSystem->Load("libStPicoEvent"); + gSystem->Load("libStPicoDstMaker"); + StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); + cout << "picoMk = " << picoMk << endl; + picoMk->setVtxMode(StPicoDstMaker::Default); + + // Generate FWD QA + StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); + fwdQAMk->SetDebug(2); + chain->AddAfter("fwdTrack", fwdQAMk); + + + + chain->Print(); // Initialize the chain chain->Init(); + // + //_____________________________________________________________________________ // // MAIN EVENT LOOP //_____________________________________________________________________________ for (int i = 0; i < n; i++) { chain->Clear(); + if ( fwdMakerGen ) + fwdMakerGen->SetDebug(1); if (kStOK != chain->Make()) break; } diff --git a/StRoot/StFwdTrackMaker/macro/daq/submit.xml b/StRoot/StFwdTrackMaker/macro/daq/submit.xml index 92676f3ff27..80111088e96 100644 --- a/StRoot/StFwdTrackMaker/macro/daq/submit.xml +++ b/StRoot/StFwdTrackMaker/macro/daq/submit.xml @@ -17,11 +17,6 @@ setup 64b starver dev - module use /cvmfs/star.sdcc.bnl.gov/star-spack/spack/share/spack/modules/linux-rhel7-x86_64/ - module load star-env-root-5.34.38 - module load kitrack-root-5.34.38 - module load genfit-root-5.34.38 - module load rave-2020-08-11 root4star -b -q -l 'daq/daq_track.C( 2, "'$INPUTFILE0'" )' diff --git a/StRoot/StFwdTrackMaker/macro/event/ana.C b/StRoot/StFwdTrackMaker/macro/event/ana.C new file mode 100755 index 00000000000..2a5861eb524 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/event/ana.C @@ -0,0 +1,42 @@ +//usr/bin/env root4star -l -b -q $0; exit $? +// that is a valid shebang to run script as executable + +void ana( int n = 5000, + const char *inFile = "sim.event.root", + const char *geom = "dev2022") { + TString _chain; + gSystem->Load( "libStarRoot.so" ); + + // Simplest chain with fst, fcs, ftt and fwdTracker + _chain = Form("in, %s, fcsdb, MakeEvent, CMuDst", geom); + + // needed in this wonky spack environment + gROOT->SetMacroPath(".:/star-sw/StRoot/macros:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + gSystem->Load("StFcsDbMaker.so"); + StFcsDbMaker* fcsdbmkr = (StFcsDbMaker*) chain->GetMaker("fcsDbMkr"); + cout << "fcsdbmkr="<GetDataSet("fcsDb"); + cout << "fcsdb="<Load("StFwdUtils.so"); + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(1); + + // Initialize the chain + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + chain->Clear(); + if (kStOK != chain->Make()) + break; + } +} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C b/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C new file mode 100644 index 00000000000..4e616a26997 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C @@ -0,0 +1,137 @@ +//usr/bin/env root4star -l root -l -q $0; exit $? +// that is a valid shebang to run script as executable, but with only one arg + +void loadLibs(); +void fwdqa( const Char_t * fileList = "mudst.lis", int nEvents = 5000, int nFiles = 1 ){ + cout << "FileList: " << fileList << endl; + cout << "nFiles: " << nFiles << endl; + cout << "nEvents: " << nEvents << endl; + + // First load some shared libraries we need + loadLibs(); + + // create the chain + StChain *chain = new StChain("StChain"); + + // create the StMuDstMaker + StMuDstMaker *muDstMaker = new StMuDstMaker( 0, + 0, + "", + fileList, + "MuDst.root", + nFiles + ); + + // Initialize the database + // cout << endl << "============ Data Base =========" << endl; + // St_db_Maker *dbMk = new St_db_Maker("db","MySQL:StarDb","$STAR/StarDb","StarDb"); + + + // gSystem->Load("StFwdUtils.so"); + // StFwdAnalysisMaker * fwdAna = new StFwdAnalysisMaker(); + // fwdAna->setMuDstInput(); + // chain->AddMaker(fwdAna); + + // StFcsDbMaker * fcsDb = new StFcsDbMaker(); + // chain->AddMaker(fcsDb); + // fcsDb->SetDebug(); + + gSystem->Load("libStarGeneratorUtil.so"); + gSystem->Load("libgenfit2"); + gSystem->Load("libKiTrack"); + gSystem->Load( "StFwdTrackMaker.so" ); + gSystem->Load("libStEpdUtil.so"); + StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); + fwdQAMk->SetDebug(2); + + // Initialize chain + Int_t iInit = chain->Init(); + + cout << "CHAIN INIT DONE?" << endl; + // ensure that the chain initializes + if ( iInit ) + chain->Fatal(iInit,"on init"); + + // print the chain status + // chain->PrintInfo(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < nEvents; i++) { + chain->Clear(); + if (kStOK != chain->Make()) + break; + } + + // Chain Finish + if (nEvents > 1) { + cout << "FINISH up" << endl; + chain->Finish(); + } + + delete chain; + + + +} + + + +void loadLibs(){ + // if (gClassTable->GetID("TTable") < 0) { + // gSystem->Load("libStar"); + // gSystem->Load("libPhysics"); + // } + cout << "LL0" << endl; + gSystem->Load("libStarClassLibrary.so"); + gSystem->Load("libStarRoot.so"); + cout << "LL1" << endl; + gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + loadSharedLibraries(); + cout << "LL2" << endl; + + gSystem->Load("StarMagField"); + gSystem->Load("StMagF"); + gSystem->Load("StDetectorDbMaker"); + gSystem->Load("StTpcDb"); + gSystem->Load("StDaqLib"); + gSystem->Load("StDbBroker"); + gSystem->Load("StDbUtilities"); + gSystem->Load("St_db_Maker"); + + gSystem->Load("StEvent"); + gSystem->Load("StEventMaker"); + gSystem->Load("StarMagField"); + + gSystem->Load("libGeom"); + gSystem->Load("St_g2t"); + + // Added for Run16 And beyond + gSystem->Load("libGeom.so"); + + gSystem->Load("St_base.so"); + gSystem->Load("StUtilities.so"); + gSystem->Load("libPhysics.so"); + gSystem->Load("StarAgmlUtil.so"); + gSystem->Load("StarAgmlLib.so"); + gSystem->Load("libStarGeometry.so"); + gSystem->Load("libGeometry.so"); + + gSystem->Load("xgeometry"); + + gSystem->Load("St_geant_Maker"); + + + // needed since I use the StMuTrack + gSystem->Load("StarClassLibrary"); + gSystem->Load("StStrangeMuDstMaker"); + gSystem->Load("StMuDSTMaker"); + gSystem->Load("StBTofCalibMaker"); + gSystem->Load("StVpdCalibMaker"); + gSystem->Load("StBTofMatchMaker"); + gSystem->Load("StFcsDbMaker"); + + +} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/mudst.C b/StRoot/StFwdTrackMaker/macro/mudst/mudst.C new file mode 100755 index 00000000000..996397d87a6 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/mudst/mudst.C @@ -0,0 +1,130 @@ +//usr/bin/env root4star -l root -l -q $0; exit $? +// that is a valid shebang to run script as executable, but with only one arg + +void loadLibs(); +void mudst( const Char_t * fileList = "mudst.lis", int nEvents = 5000, int nFiles = 1 ){ + cout << "FileList: " << fileList << endl; + cout << "nFiles: " << nFiles << endl; + cout << "nEvents: " << nEvents << endl; + + // First load some shared libraries we need + loadLibs(); + + // create the chain + StChain *chain = new StChain("StChain"); + + // create the StMuDstMaker + StMuDstMaker *muDstMaker = new StMuDstMaker( 0, + 0, + "", + fileList, + "MuDst.root", + nFiles + ); + + // Initialize the database + // cout << endl << "============ Data Base =========" << endl; + // St_db_Maker *dbMk = new St_db_Maker("db","MySQL:StarDb","$STAR/StarDb","StarDb"); + + + gSystem->Load("StFwdUtils.so"); + StFwdAnalysisMaker * fwdAna = new StFwdAnalysisMaker(); + fwdAna->setMuDstInput(); + chain->AddMaker(fwdAna); + + StFcsDbMaker * fcsDb = new StFcsDbMaker(); + chain->AddMaker(fcsDb); + fcsDb->SetDebug(); + + + // Initialize chain + Int_t iInit = chain->Init(); + + cout << "CHAIN INIT DONE?" << endl; + // ensure that the chain initializes + if ( iInit ) + chain->Fatal(iInit,"on init"); + + // print the chain status + // chain->PrintInfo(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < nEvents; i++) { + chain->Clear(); + if (kStOK != chain->Make()) + break; + } + + // Chain Finish + if (nEvents > 1) { + cout << "FINISH up" << endl; + chain->Finish(); + } + + delete chain; + + + +} + + + +void loadLibs(){ + // if (gClassTable->GetID("TTable") < 0) { + // gSystem->Load("libStar"); + // gSystem->Load("libPhysics"); + // } + cout << "LL0" << endl; + gSystem->Load("libStarClassLibrary.so"); + gSystem->Load("libStarRoot.so"); + cout << "LL1" << endl; + gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + loadSharedLibraries(); + cout << "LL2" << endl; + + gSystem->Load("StarMagField"); + gSystem->Load("StMagF"); + gSystem->Load("StDetectorDbMaker"); + gSystem->Load("StTpcDb"); + gSystem->Load("StDaqLib"); + gSystem->Load("StDbBroker"); + gSystem->Load("StDbUtilities"); + gSystem->Load("St_db_Maker"); + + gSystem->Load("StEvent"); + gSystem->Load("StEventMaker"); + gSystem->Load("StarMagField"); + + gSystem->Load("libGeom"); + gSystem->Load("St_g2t"); + + // Added for Run16 And beyond + gSystem->Load("libGeom.so"); + + gSystem->Load("St_base.so"); + gSystem->Load("StUtilities.so"); + gSystem->Load("libPhysics.so"); + gSystem->Load("StarAgmlUtil.so"); + gSystem->Load("StarAgmlLib.so"); + gSystem->Load("libStarGeometry.so"); + gSystem->Load("libGeometry.so"); + + gSystem->Load("xgeometry"); + + gSystem->Load("St_geant_Maker"); + + + // needed since I use the StMuTrack + gSystem->Load("StarClassLibrary"); + gSystem->Load("StStrangeMuDstMaker"); + gSystem->Load("StMuDSTMaker"); + gSystem->Load("StBTofCalibMaker"); + gSystem->Load("StVpdCalibMaker"); + gSystem->Load("StBTofMatchMaker"); + gSystem->Load("StFcsDbMaker"); + + +} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/pico.C b/StRoot/StFwdTrackMaker/macro/mudst/pico.C new file mode 100755 index 00000000000..7ff3f3a63ee --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/mudst/pico.C @@ -0,0 +1,602 @@ +//usr/bin/env root4star -l -b -q $0; exit $? +///////////////////////////////////////////////////////////////////////////// +// $Id: genDst.C,v 1.9 2020/10/10 07:16:56 genevb Exp $ +// Author: G. Van Buren (BNL) +// +// Description: +// Process a MuDst for... +// ...creating a PicoDst +// ...re-running vertex-finding to re-create MuDsts +// +// Options are space-separated or comma-separated, +// and case-insensitive. They can be attributed +// whose values are provided after a ':'. +// +// Example options for creating PicoDsts: +// picoDst +// btofMatch +// btofStartless +// mtdMatch +// y2017a +// +// Example lists of options: +// "picoDst" +// "DbV20200125,picoDst,mtdMatch,y2014a" +// +// Example options for vertex-finding: +// beamline, beamline1D, beamline3D (otherwise no beamline) +// useBTOFmatchOnly +// VFstore:100 +// +// Example lists of options: +// "VFPPVnoCTB,beamline1D,VFstore:100" +// "VFPPVnoCTB,beamline3D" +// +///////////////////////////////////////////////////////////////////////////// + +void afterburner(); + +void genDst(unsigned int Last, + const char* options, + char* infile, + char* outfile=0); + +void genDst(unsigned int First, + unsigned int Last, + const char* options, + char* infile, + char* outfile=0); + +void loadLibs() +{ + gROOT->Macro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + gSystem->Load("StDbBroker"); + gSystem->Load("St_db_Maker"); + gSystem->Load("StEEmcUtil"); +} + +void loadLibsVF() +{ + gSystem->Load("libMinuit"); + gSystem->Load("Sti"); + gSystem->Load("StBTofUtil"); + gSystem->Load("StGenericVertexMaker"); +} + +void loadLibsPico() +{ + + // EMCs and FMS need DB+converters + gSystem->Load("StEmcRawMaker"); + gSystem->Load("StEmcADCtoEMaker"); + gSystem->Load("StPreEclMaker"); + gSystem->Load("StEpcMaker"); + gSystem->Load("StEEmcDbMaker"); + gSystem->Load("StFmsUtil"); + gSystem->Load("StFmsDbMaker"); + gSystem->Load("StTriggerUtilities"); + + // The PicoDst + gSystem->Load("libStPicoEvent"); + gSystem->Load("libStPicoDstMaker"); +} + +void loadLibsAgML() +{ + // load support libraries. util will fail to load for agml 1.0, but you can ignore the error + gSystem->Load("libStarAgmlUtil"); + gSystem->Load("libStarAgmlLib"); + + // load geometry modules and master steering codes... + gSystem->Load("libGeometry"); + gSystem->Load("libStarGeometry"); +} + +void loadLibsMtd() +{ + gSystem->Load("StDetectorDbMaker"); + gSystem->Load("StarMagField"); + gSystem->Load("StMagF"); + gSystem->Load("StMtdUtil"); + gSystem->Load("StMtdMatchMaker"); + gSystem->Load("StMtdCalibMaker"); +} + +void loadLibsBTof() +{ + gSystem->Load("StBTofUtil"); + gSystem->Load("StVpdCalibMaker"); + gSystem->Load("StBTofCalibMaker"); + gSystem->Load("StBTofMatchMaker"); +} + +void loadLibsETof() +{ + gSystem->Load("StETofUtil"); + gSystem->Load("StETofCalibMaker"); + gSystem->Load("StETofHitMaker"); + gSystem->Load("StETofMatchMaker"); +} + +void loadLibsFwd() +{ + gSystem->Load("libStDetectorDbMaker.so"); + gSystem->Load("StEvent"); + gSystem->Load("StEventMaker"); + + // Fwd + gSystem->Load("StFwdUtils"); + gSystem->Load("libStarGeneratorUtil.so"); + gSystem->Load("libXMLIO"); + gSystem->Load("libgenfit2"); + gSystem->Load("libKiTrack"); + // gSystem->Load("StarGeneratorUtil") ; + gSystem->Load("libMathMore"); + gSystem->Load("StEventUtilities"); + gSystem->Load("StEpdUtil"); + gSystem->Load("StFwdTrackMaker"); + gSystem->Load("StFwdUtils"); + //Ftt + gSystem->Load("StFttDbMaker"); + gSystem->Load("StFttRawHitMaker"); + gSystem->Load("StFttHitCalibMaker"); + gSystem->Load("StFttClusterMaker"); + gSystem->Load("StFttPointMaker"); + // Fcs + gSystem->Load("libMinuit.so"); + gSystem->Load("StFcsDbMaker"); + gSystem->Load("StFcsRawHitMaker"); + gSystem->Load("StFcsWaveformFitMaker"); + gSystem->Load("StFcsClusterMaker"); + gSystem->Load("StFcsPointMaker"); + gSystem->Load("StFcsTrackMatchMaker"); + + // Fst + gSystem->Load("StFstUtil"); + gSystem->Load("StFstDbMaker"); + gSystem->Load("StFstRawHitMaker"); + gSystem->Load("StFstClusterMaker"); + gSystem->Load("StFstHitMaker"); +} + +void procGeoTag(TObjArray* optionTokens) +{ + if (TClass::GetClass("AgBlock")) return; // arbitrarily chosen AgML class + loadLibsAgML(); + + const char* tag = 0; + for (int tk=0; tk < optionTokens->GetEntries(); tk++) { + TString& tok = ((TObjString*) (optionTokens->At(tk)))->String(); + if (tok.BeginsWith("y20")){ + tag = tok.Data(); + optionTokens->RemoveAt(tk); + optionTokens->Compress(); + break; + } + } + + // Let agml know we want the ROOT geometry + AgModule::SetStacker( new StarTGeoStacker ); + + // now pass the geometry "tag" and build. If the class StarGeometry exists, we have + // AgML 2.0 and can run using the new steering. Otherwise, old steering codes... + if (tag) { + if ( TClass::GetClass("StarGeometry") ) { StarGeometry::Construct( tag ); } + else { ( new Geometry() )->ConstructGeometry(tag); } + } else { + gMessMgr->Warning() << "No geometry tag passed! (e.g. y2017a)" << endm; + } +} + +bool findAndRemoveOption(const char* optionName, TObjArray* optionTokens) +{ + TString optName = optionName; + optName.ToLower(); + TObject* obj = optionTokens->FindObject(optName.Data()); + if (obj) { + optionTokens->Remove(obj); + optionTokens->Compress(); + return true; + } + return false; +} + +void genDst(unsigned int First, + unsigned int Last, + const char* options, + char* infile, + char* outfile) +{ + loadLibs(); + + StChain fullChain("genDst"); + fullChain.SetDebug(1); + + StMuDstMaker muDstMaker(0, 0, "", infile, "st:MuDst.root", 1e9); // set up maker in read mode + // 0, 0 this means read mode + // dir read all files in this directory + // file bla.lis read all file in this list, if (file!="") dir is ignored + // filter apply filter to filenames, multiple filters are separated by ':' + // 10 maximum number of file to read + + + TChain& muDstChain = *muDstMaker.chain(); + unsigned int nEntries = muDstChain.GetEntries(); + unsigned int LastToRead = Last > 0 ? min(Last, nEntries) : nEntries; + gMessMgr->Info() << nEntries << " events in chain, " << LastToRead-First+1 << " will be read." << endm; + + // St_db_Maker* db = new St_db_Maker("db", "StarDb", "MySQL:StarDb", "$STAR/StarDb"); + + // Initialize some values and pointers + StMaker* processMaker = 0; + TFile* outFile = 0; + TTree* muDstTreeOut = 0; + + // Basic decisions based on options + TString CasedOptions = options; + TString Options = options; + Options.ToLower(); + TString optDelim = " ,"; + TObjArray* optionTokens = Options.Tokenize(optDelim); + optionTokens->SetOwner(kTRUE); + + // Determine database flavors + TString flavors = "ofl"; // default flavor for offline + + // simulation flavors + if (findAndRemoveOption("Simu",optionTokens) && ! findAndRemoveOption("NoSimuDb",optionTokens)) + flavors.Prepend("sim+"); + + // filestream flavors + TObject* firstFile = muDstChain.GetListOfFiles()->At(0); + if (firstFile) { + TString firstFileName = firstFile->GetTitle(); + firstFileName = firstFileName(firstFileName.Last('/')+1,firstFileName.Length()); + if (firstFileName.BeginsWith("st_")) { + TString fileStream = firstFileName(3,firstFileName.Index('_',3)-3); + if (fileStream.Length()>0) flavors.Prepend(fileStream += '+'); + } + } + + // gMessMgr->Info() << "Using DB flavors: " << flavors << endm; + // db->SetFlavor(flavors.Data()); + + if (findAndRemoveOption("picodst",optionTokens)) { + // _________________________________________________________________ + // Processing with generation of PicoDsts + + loadLibsPico(); + + // Specify active branches but first disable all branches + muDstMaker.SetStatus("*", 0); + muDstMaker.SetStatus("MuEvent", 1); + muDstMaker.SetStatus("PrimaryVertices", 1); + muDstMaker.SetStatus("PrimaryTracks", 1); + muDstMaker.SetStatus("GlobalTracks", 1); + muDstMaker.SetStatus("CovGlobTrack", 1); + muDstMaker.SetStatus("BTof*", 1); + muDstMaker.SetStatus("Emc*", 1); + muDstMaker.SetStatus("MTD*", 1); + muDstMaker.SetStatus("ETof*", 1); + muDstMaker.SetStatus("Epd*", 1); + muDstMaker.SetStatus("Fms*", 1); + muDstMaker.SetStatus("MCAll", 1); + muDstMaker.SetStatus("Fwd*", 1); + muDstMaker.SetStatus("Fcs*", 1); + muDstMaker.SetStatus("Ftt*", 1); + muDstMaker.SetStatus("Fst*", 1); + + // EMCs + // StEEmcDbMaker* eemcDb = new StEEmcDbMaker; + // StEmcADCtoEMaker* adc2e = new StEmcADCtoEMaker(); + // adc2e->saveAllStEvent(true); + // StPreEclMaker* pre_ecl = new StPreEclMaker(); + // StEpcMaker* epc = new StEpcMaker(); + + // FMS + // StFmsDbMaker* fmsDb = new StFmsDbMaker("fmsDb"); + + // Trigger simulator + // StTriggerSimuMaker* trigSimu = new StTriggerSimuMaker; + // trigSimu->setMC(false); + // trigSimu->useBemc(); + // trigSimu->useEemc(); + // trigSimu->useOfflineDB(); + // trigSimu->bemc->setConfig(StBemcTriggerSimu::kOffline); + + loadLibsFwd(); + + // If you need the geometry you can load it with this: + // gROOT->LoadMacro("/star-sw/StarVMC/Geometry/macros/loadStarGeometry.C"); + // loadStarGeometry( "y2023" ); + + // This makes the Fcs and Ftt hits show up in StEvent, + // and produces an StEvent for StFwdTracks to go into + StMuDst2StEventMaker * mu2ev = new StMuDst2StEventMaker(); + + // Re-run the FCS chain + StFcsDbMaker * fcsDbMk = new StFcsDbMaker(); + // StFcsWaveformFitMaker * fcsWFF = new StFcsWaveformFitMaker(); + // StFcsClusterMaker * fcsClu = new StFcsClusterMaker(); + // StFcsPointMaker * fcsPoint = new StFcsPointMaker(); + + // FTT chain + StFttDbMaker * fttDbMk = new StFttDbMaker(); + StFttHitCalibMaker * ftthcm = new StFttHitCalibMaker(); + StFttClusterMaker * fttclu = new StFttClusterMaker(); + fttclu->SetTimeCut(1, -40, 40); + StFttPointMaker * fttpoint = new StFttPointMaker(); + + + StFwdTrackMaker * fwdTrack = new StFwdTrackMaker(); + fwdTrack->setConfigForData( ); + fwdTrack->setGeoCache( "fGeom.root" ); + fwdTrack->setSeedFindingWithFst(); + fwdTrack->setIncludePrimaryVertexInFit(true); + fwdTrack->setMaxFailedHitsInFit(2); + fwdTrack->SetDebug(2); + + StFcsTrackMatchMaker *match = new StFcsTrackMatchMaker(); + match->setMaxDistance(6,10); + match->setFileName("fcstrk.root"); + match->SetDebug(); + + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(); + fwdAna->setLocalOutputFile( "StFwdAnalysisMaker.root"); + + StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); + fwdFitQA->SetDebug(); + + StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); + fwdQAMk->SetDebug(2); + // chain->AddAfter("fwdTrack", fwdQAMk); + + if (findAndRemoveOption("btofmatch",optionTokens)) { + + procGeoTag(optionTokens); + loadLibsBTof(); + + // instantiate both VPD and BTOF CalibMakers and MatchMaker and point them to the MuDST + StBTofMatchMaker* btofMatch = new StBTofMatchMaker(); + btofMatch->setMuDstIn(); + StVpdCalibMaker *vpdCalib = new StVpdCalibMaker(); + vpdCalib->setMuDstIn(); + StBTofCalibMaker *btofCalib = new StBTofCalibMaker(); + btofCalib->setMuDstIn(); + + if (findAndRemoveOption("btofstartless",optionTokens)) { + //Disable the VPD as start detector, BTOF calib maker will switch to the "start-less" algorithm. + vpdCalib->setUseVpdStart(kFALSE); + } + + } + + if (findAndRemoveOption("etofmatch",optionTokens)) { + + procGeoTag(optionTokens); + loadLibsETof(); + + // instantiate eTOF CalibMakers, HitMaker and MatchMaker + StETofCalibMaker* etofCalib = new StETofCalibMaker(); + StETofHitMaker* etofHit = new StETofHitMaker(); + StETofMatchMaker* etofMatch = new StETofMatchMaker(); + + } + + if (findAndRemoveOption("mtdmatch",optionTokens)) { + + procGeoTag(optionTokens); + loadLibsMtd(); + + StMagFMaker* magfMk = new StMagFMaker; + StMtdMatchMaker* mtdMatchMaker = new StMtdMatchMaker(); + StMtdCalibMaker* mtdCalibMaker = new StMtdCalibMaker("mtdcalib"); + + } + + processMaker = (StMaker*) (new StPicoDstMaker(StPicoDstMaker::IoWrite, infile, "picoDst")); + StPicoDstMaker *picoMk = (StPicoDstMaker*) (processMaker); + picoMk->setVtxMode(StPicoDstMaker::Vpd); + gMessMgr->Info() << "PicoSetup Complete" << endm; + } else if (Options.Contains("fwd")) { + // _________________________________________________________________ + // Processing with new vertex-finding + + // loadLibsVF(); + + // Specify inactive branches but first enable all branches + muDstMaker.SetStatus("*",1); + muDstMaker.SetStatus("PrimaryTracks",0); + muDstMaker.SetStatus("PrimaryVertices",0); + + // Create new branch + // TClonesArray* verticesRefitted = new TClonesArray("StMuPrimaryVertex", 1000); + + // Specify output + if (outfile) { + outFile = new TFile(outfile, "RECREATE"); + } else { + // Use the same filename for output as was given by input + TString fileStr = infile; + Ssiz_t dir = fileStr.Last('/'); + if (dir<0) { + gMessMgr->Error() << "No specification for output when input is in local directory!" << endm; + return; + } + fileStr.Remove(0,dir+1); + outFile = new TFile(fileStr.Data(), "RECREATE"); + } + muDstTreeOut = muDstChain.CloneTree(0); + muDstTreeOut->Branch("PrimaryVertices", &verticesRefitted, 65536, 99); + + // processMaker = (StMaker*) (new StGenericVertexMaker()); + // processMaker->ToWhiteConst("vtxArray",verticesRefitted); + // processMaker->SetAttr("useMuDst",1); + + } else { + + gMessMgr->Info() << "No processing specified - just reading a MuDst?" << endm; + // User code may be inserted here + + } + + // Set additional options (except DbV) as maker attributes + if (processMaker) { + for (int tk=0; tk < optionTokens->GetEntries(); tk++) { + TString& Tag = ((TObjString*) (optionTokens->At(tk)))->String(); + + // copy of DbV code from StBFChain.cxx + if (Tag.BeginsWith("dbv")) { + int FDate=0,FTime=0; + if (Tag.Length() == 11) (void) sscanf(Tag.Data(),"dbv%8d",&FDate); + if (Tag.Length() == 18) (void) sscanf(Tag.Data(),"dbv%8d.%6d",&FDate,&FTime); + if (FDate) { + // db->SetMaxEntryTime(FDate,FTime); + // gMessMgr->Info() << "\tSet DataBase max entry time " << FDate << "/" << FTime + // << " for St_db_Maker(\"" << db->GetName() <<"\")" << endm; + } + continue; + } + + // assign attributes + StMaker* attrMaker = processMaker; + Ssiz_t delim = Tag.First(':'); + // look for "::" to set attributes for a different maker + if (delim > 0 && Tag[delim+1] == ':') { + TString altMakerName = Tag(0,delim); + // GetMaker...() functions are case sensitive, so find original case + Ssiz_t casedMakerNameIdx = CasedOptions.Index(altMakerName,0,TString::ECaseCompare::kIgnoreCase); + if (casedMakerNameIdx >= 0) altMakerName = CasedOptions(casedMakerNameIdx,delim); + StMaker* altMaker = fullChain.GetMaker(altMakerName.Data()); + if (!altMaker) altMaker = fullChain.GetMakerInheritsFrom(altMakerName.Data()); + if (!altMaker) { + gMessMgr->Warning() << "No maker found with name or class " << altMakerName.Data() << endm; + continue; + } + attrMaker = altMaker; + Tag.Remove(0,delim+2); + delim = Tag.First(':'); + } + if (delim < 0) { + attrMaker->SetAttr(Tag.Data(),1); + } else { + TString key(Tag(0,delim)); + TString& val = Tag.Remove(0,delim+1); + if (val.IsDigit()) { attrMaker->SetAttr(key.Data(),val.Atoi()); } + else if (val.IsFloat()) { attrMaker->SetAttr(key.Data(),val.Atof()); } + else { attrMaker->SetAttr(key.Data(),val.Data()); } + } + } + processMaker->PrintAttr(); + } + + { + TDatime t; + gMessMgr->QAInfo() << Form("Run is started at Date/Time %i/%i",t.GetDate(),t.GetTime()) << endm; + } + gMessMgr->QAInfo() << Form("Run on %s in %s",gSystem->HostName(),gSystem->WorkingDirectory()) << endm; + gMessMgr->QAInfo() << Form("with %s", fullChain.GetCVS()) << endm; + + gMessMgr->Info() << "Chain setup Complete" << endm; + + // Main loop over events + int iInit = fullChain.Init(); + if (iInit >= kStEOF) {fullChain.FatalErr(iInit,"on init"); return;} + if (Last == 0) return; + int eventCount = 0; + // Skip, if any + if (First > 1) fullChain.Skip(First - 1); + for (unsigned int iEvent = First; iEvent <= LastToRead; iEvent++) + { + // make an StEvent so that Fwd can save tracks, etc. + // StEvent * stEv = new StEvent(); + // fullChain.AddData( stEv ); + fullChain.SetDebug(2); + fwdTrack->SetDebug(2); + + int iMake = fullChain.Make(); + if (iMake) {fullChain.FatalErr(iMake,"on make"); return;} + + if (muDstTreeOut) muDstTreeOut->Fill(); + + int iClear = fullChain.Clear(); + if (iClear) {fullChain.FatalErr(iClear,"on clear"); return;} + eventCount++; + } + fullChain.Finish(); + + // + // ATTENTION - please DO NOT change the format of the next 2 lines, + // they are used by our DataManagement parsers to detect a generation + // was succesful and thereafter Catalog the produced files. + // Thank you. + // + gMessMgr->QAInfo() << "NumberOfEvents= " << eventCount << endm; + gMessMgr->QAInfo() << "Run completed " << endm; + + if (outFile) { + outFile->Write(); + outFile->Close(); + delete outFile; + } + + // delete db; + delete processMaker; + delete optionTokens; +} + +//__________________________________________________________ +void genDst(unsigned int Last, + const char* options, + char* infile, + char* outfile) +{ + cout << TString::Format("genDst( %u, '%s', '%s', '%s' )", Last, options, infile, outfile ) << endl; + genDst(1,Last,options,infile,outfile); +} + +void pico(){ + genDst(5000, "y2023a picodst PicoVtxMode:PicoVtxDefault", "/work/st_fwd_22355048_raw_1000012.MuDst.root", "PROD.root"); +} + +void pico( TString f, int n = 500){ + genDst(n, "y2023a picodst PicoVtxMode:PicoVtxDefault", f.Data(), "PROD.root" /*Not used?*/); +} + +///////////////////////////////////////////////////////////////////////////// +// +// $Log: genDst.C,v $ +// Revision 1.10 2022/05/12 07:16:56 weidenkaff +// Added eTOF support +// +// $Log: genDst.C,v $ +// Revision 1.9 2020/10/10 07:16:56 genevb +// Specify makers to set attributes +// +// Revision 1.8 2020/08/19 15:27:33 genevb +// Add DB flavors +// +// Revision 1.7 2020/01/25 05:10:00 genevb +// Include DbV, more like BFC +// +// Revision 1.6 2019/09/18 17:54:48 genevb +// Acivate additional branches by default +// +// Revision 1.5 2019/03/21 18:53:34 jeromel +// Added ATTENTION message +// +// Revision 1.4 2019/01/15 17:24:29 genevb +// Added FMS +// +// Revision 1.3 2018/03/16 18:41:14 genevb +// Add BTof-matching +// +// Revision 1.2 2017/12/15 18:36:53 genevb +// Remove explicit function of StPicoDstMaker...params should be passed by attribute +// +// Revision 1.1 2017/12/05 16:47:58 genevb +// Introduce genDst.C for creating new Dsts from MuDsts +// +// +///////////////////////////////////////////////////////////////////////////// diff --git a/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml b/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml new file mode 100644 index 00000000000..d6279fd1c97 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + echo "JOBINDEX = ${JOBINDEX}" + echo "JOBID = ${JOBID}" + + ln -s StRoot/StFwdTrackMaker/macro/mudst/ mudst + ls -lah + + starver dev + root4star -b -q -l 'mudst/pico.C( "'$INPUTFILE0'", 50000 )' + + mv StFwdAnalysisMaker.root ${JOBID}_StFwdAnalysisMaker.root + mv StFwdFitQAMaker.root ${JOBID}_StFwdFitQAMaker.root + + + + + file:./StRoot + file:./fGeom.root + file:.sl73_gcc485/ + + + + + /gpfs01/star/pwg_tasks/FwdCalib/PROD/gen + + diff --git a/StRoot/StFwdTrackMaker/macro/qa/mudst.C b/StRoot/StFwdTrackMaker/macro/qa/mudst.C new file mode 100755 index 00000000000..966097b055b --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/qa/mudst.C @@ -0,0 +1,78 @@ +//usr/bin/env root4star -l -b -q $0'("'$1'")'; exit $? + +#include "TTree.h" +#include "TClonesArray.h" + +void mudst( TString df = "sim.MuDst.root" ){ + + // setup and make sure libraries are loaded + gSystem->Load( "libStarRoot.so" ); + gSystem->Load("libStarClassLibrary.so"); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + loadSharedLibraries(); + + gSystem->Load("libgenfit2.so"); + gSystem->Load("libKiTrack.so"); + gSystem->Load( "libStFwdTrackMaker.so" ); + + // now open our data file + TFile *f = new TFile(df); + TTree *t = (TTree*)f->Get("MuDst"); + + // create the readers for each branch + // TClonesArray *mcTracks = new TClonesArray("StMuMcTrack"); + // t->GetBranch("mcTracks")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("mcTracks",&mcTracks); + + // TClonesArray *fttPoints = new TClonesArray("StMuFttPoint"); + // t->GetBranch("fttPoints")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("fttPoints",&fttPoints); + + // TClonesArray *fttClusters = new TClonesArray("StMuFttCluster"); + // t->GetBranch("fttClusters")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("fttClusters",&fttClusters); + + // TClonesArray *fstPoints = new TClonesArray("StMuFstHit"); + // t->GetBranch("fstHits")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("fstHits",&fstPoints); + + // TClonesArray *wcal = new TClonesArray("FcsClusterWithStarXYZ"); + // t->GetBranch("wcalClusters")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("wcalClusters",&wcal); + + // TClonesArray *wcalHits = new TClonesArray("FcsHitWithStarXYZ"); + // t->GetBranch("wcalHits")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("wcalHits",&wcalHits); + + // TClonesArray *hcal = new TClonesArray("FcsClusterWithStarXYZ"); + // t->GetBranch("hcalClusters")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("hcalClusters",&hcal); + + // TClonesArray *hcalHits = new TClonesArray("FcsHitWithStarXYZ"); + // t->GetBranch("hcalHits")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("hcalHits",&hcalHits); + + // TClonesArray *epdHits = new TClonesArray("FcsHitWithStarXYZ"); + // t->GetBranch("epdHits")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("epdHits",&epdHits); + + TClonesArray *fwdTracks = new TClonesArray("StMuFwdTrack"); + t->GetBranch("FwdTrack")->SetAutoDelete(kFALSE); + t->SetBranchAddress("FwdTrack",&fwdTracks); + + // TClonesArray *seeds = new TClonesArray("StMuFwdTrackSeedPoint"); + // t->GetBranch("seeds")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("seeds",&seeds); + + + //loop over the events + for ( int i = 0; i < t->GetEntries(); i++ ){ + t->GetEntry(i); + for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ + StMuFwdTrack *track = fwdTracks->At(j); + printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); + } + } + cout << "Processed: " << t->GetEntries() << " entries" << endl; +} \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/qa/qa.C b/StRoot/StFwdTrackMaker/macro/qa/qa.C new file mode 100755 index 00000000000..926d9e1d472 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/qa/qa.C @@ -0,0 +1,281 @@ +//usr/bin/env root4star -l -b -q $0'("'"$1"'")'; exit $? + +#include "TTree.h" +#include "TClonesArray.h" +#include +// #include <__config> + +// TClonesArrays to read from the tree +TClonesArray *mcTracks = NULL; +TClonesArray *fttPoints = NULL; +TClonesArray *fttClusters = NULL; +TClonesArray *fstPoints = NULL; +TClonesArray *wcal = NULL; +TClonesArray *wcalHits = NULL; +TClonesArray *hcal = NULL; +TClonesArray *hcalHits = NULL; +TClonesArray *epdHits = NULL; +TClonesArray *fwdTracks = NULL; +TClonesArray *seeds = NULL; +TTree *t = NULL; + +std::map histograms; +TH1* addH1( string name, string title, int nx, float x1, float x2 ){ + histograms[name] = new TH1F( name.c_str(), title.c_str(), nx, x1, x2 ); + return histograms[name]; +} +TH2* addH2( string name, string title, int nx, float x1, float x2, int ny, float y1, float y2 ){ + histograms[name] = new TH2F( name.c_str(), title.c_str(), nx, x1, x2, ny, y1, y2 ); + return (TH2*)histograms[name]; +} +inline TH1 *getH1( string name ){ + // printf( "Looking for histogram name=[%s]", name.c_str() ); + assert( histograms.count( name ) && "Histogram cannot be found" && name.c_str() ); + assert( histograms[name] && TString::Format( "Histogram %s is NULL", name.c_str() ) ); + return histograms[name]; +} +inline TH2 *getH2( string name ){ + return (TH2*) getH1( name ); +} + +void setupRead( TString filename = "fwdtree.root" ){ + // setup and make sure libraries are loaded + gSystem->Load( "libStarRoot.so" ); + gSystem->Load("libStarClassLibrary.so"); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + loadSharedLibraries(); + + gSystem->Load("libgenfit2.so"); + gSystem->Load("libKiTrack.so"); + gSystem->Load( "libStFwdTrackMaker.so" ); + + // now open our data file + TFile *f = new TFile(filename); + t = (TTree*)f->Get("fwd"); + + // create the readers for each branch + mcTracks = new TClonesArray("StMuMcTrack"); + t->GetBranch("mcTracks")->SetAutoDelete(kFALSE); + t->SetBranchAddress("mcTracks",&mcTracks); + + fttPoints = new TClonesArray("StMuFttPoint"); + t->GetBranch("fttPoints")->SetAutoDelete(kFALSE); + t->SetBranchAddress("fttPoints",&fttPoints); + + fttClusters = new TClonesArray("StMuFttCluster"); + t->GetBranch("fttClusters")->SetAutoDelete(kFALSE); + t->SetBranchAddress("fttClusters",&fttClusters); + + fstPoints = new TClonesArray("StMuFstHit"); + t->GetBranch("fstHits")->SetAutoDelete(kFALSE); + t->SetBranchAddress("fstHits",&fstPoints); + + wcal = new TClonesArray("FcsClusterWithStarXYZ"); + t->GetBranch("wcalClusters")->SetAutoDelete(kFALSE); + t->SetBranchAddress("wcalClusters",&wcal); + + wcalHits = new TClonesArray("FcsHitWithStarXYZ"); + t->GetBranch("wcalHits")->SetAutoDelete(kFALSE); + t->SetBranchAddress("wcalHits",&wcalHits); + + hcal = new TClonesArray("FcsClusterWithStarXYZ"); + t->GetBranch("hcalClusters")->SetAutoDelete(kFALSE); + t->SetBranchAddress("hcalClusters",&hcal); + + hcalHits = new TClonesArray("FcsHitWithStarXYZ"); + t->GetBranch("hcalHits")->SetAutoDelete(kFALSE); + t->SetBranchAddress("hcalHits",&hcalHits); + + epdHits = new TClonesArray("FcsHitWithStarXYZ"); + t->GetBranch("epdHits")->SetAutoDelete(kFALSE); + t->SetBranchAddress("epdHits",&epdHits); + + fwdTracks = new TClonesArray("StMuFwdTrack"); + t->GetBranch("reco")->SetAutoDelete(kFALSE); + t->SetBranchAddress("reco",&fwdTracks); + + seeds = new TClonesArray("StMuFwdTrackSeedPoint"); + t->GetBranch("seeds")->SetAutoDelete(kFALSE); + t->SetBranchAddress("seeds",&seeds); +} + +void qaMomentumResolution(){ + + if ( histograms.count( "curveRcVsMc" ) == 0 ) { + printf( "Creating Momentum Resolution Histograms\n" ); + addH2( "curveRcVsMc", "Track curvature; MC; RC", 200, -10, 10, 200, -10, 10 ); + addH2( "curveMcVsPtMc", ";MC Pt; MC Curve ", 200, 0, 10, 100, 0, 10 ); + addH2( "ptRcVsMc", "Track Pt; MC; RC", 200, 0, 10, 200, 0, 10 ); + addH1( "curveRes", "Curvature Resolution; (C^{MC}-C^{RC})/C^{MC}", 200, -2, 2 ); + addH1( "transMomRes", "Pt Resolution; (Pt^{MC} - Pt^{RC}) / Pt^{MC}", 200, -2, 2 ); + addH1( "deltaCharge", "deltaCharge; |q_{MC}-q_{RC}|;counts;", 5, 0, 5 ); + } + + const TH2 * hCurveRcVsMc = getH2( "curveRcVsMc" ); + const TH2 * hCurveMcVsPtMc = getH2( "curveMcVsPtMc" ); + const TH2 * hPtRcVsMc = getH2( "ptRcVsMc" ); + + const TH1 * hCurveRes = getH1( "curveRes" ); + const TH1 * hTransMomRes = getH1( "transMomRes" ); + const TH1 * hDeltaCharge = getH1( "deltaCharge" ); + + for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ + + StMuFwdTrack *fwt = fwdTracks->At(j); + UShort_t indexToMatchedMC = fwt->idTruth() - 1; + // // cout << "Processing track " << j << ", mcid = " << indexToMatchedMC << endl; + if (indexToMatchedMC >= mcTracks->GetEntries()) continue; + // // get corresponding MC track + StMuMcTrack *mct = mcTracks->At(indexToMatchedMC); + + float curveMc = fabs(mct->Charge() / mct->pT()); + float curveRc = fabs(fwt->charge() / fwt->momentum().Pt()); + // // cout << "mct->pT() = " << mct->pT() << endl; + if ( mct->pT() > 0.1 && fwt->pval() > 0.01){ + hDeltaCharge->Fill( abs( mct->Charge() - fwt->charge() ) ); + hCurveRes->Fill( (curveMc - curveRc) / curveMc ); + hTransMomRes->Fill( (mct->pT() - fwt->momentum().Pt()) / mct->pT() ); + + hCurveRcVsMc->Fill( curveMc, curveRc ); + hCurveMcVsPtMc->Fill( curveMc, mct->pT() ); + hPtRcVsMc->Fill( mct->pT(), fwt->momentum().Pt() ); + } + } +} + +void qaFCSTrackMatch(){ + + if (histograms.count("dxWCAL") == 0){ + addH1( "dxWCAL", "WCAL; dx", 500, -100, 100 ); + addH1( "dxWCAL2", "WCAL; dx", 500, -100, 100 ); + addH1( "dyWCAL", "WCAL; dy", 500, -100, 100 ); + addH1( "dxHCAL", "HCAL; dx", 500, -100, 100 ); + addH1( "drWCAL", "WCAL; dr", 500, 0, 100 ); + addH1( "drHCAL", "HCAL; dr", 500, 0, 100 ); + addH2( "wcalTrackX", "; WCAL x; Track x", 500, -50, 50, 500, -50, 50 ); + addH2( "wcalTrackY", "; WCAL y; Track y", 500, -50, 50, 500, -50, 50 ); + } + + const TH1 * hdxWCAL = getH1("dxWCAL"); + const TH1 * hdxWCAL2 = getH1("dxWCAL2"); + const TH1 * hdyWCAL = getH1("dyWCAL"); + const TH1 * hdxHCAL = getH1("dxHCAL"); + + const TH1 * hdrWCAL = getH1("drWCAL"); + const TH1 * hdrHCAL = getH1("drHCAL"); + + const TH2 * hWCALX = getH1("wcalTrackX"); + const TH2 * hWCALY = getH1("wcalTrackY"); + + for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ + StMuFwdTrack *track = (StMuFwdTrack *)fwdTracks->At(j); + + // printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); + if ( track->pval() < 0.01 ) continue; + StMuFwdTrackProjection projWCAL; + track->getProjectionFor(kFcsWcalId, projWCAL); + // printf("Projection @ WCAL: det=%d, x=%f, y=%f, z=%f\n", projWCAL.mDetId, projWCAL.mXYZ.X(), projWCAL.mXYZ.Y(), projWCAL.mXYZ.Z()); + + StMuFwdTrackProjection projHCAL; + track->getProjectionFor(kFcsHcalId, projHCAL); + // printf("Projection @ HCAL: det=%d, x=%f, y=%f, z=%f\n", projHCAL.mDetId, projHCAL.mXYZ.X(), projHCAL.mXYZ.Y(), projHCAL.mXYZ.Z()); + + // loop over WCAL clusters + for ( int k = 0; k < wcal->GetEntries(); k++ ){ + FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); + double dx = projWCAL.mXYZ.X() - cluster->mXYZ.X(); + double dy = projWCAL.mXYZ.Y() - cluster->mXYZ.Y(); + double dr = sqrt( dx*dx + dy*dy ); + + hdxWCAL2->Fill( dx ); + if ( projWCAL.mXYZ.X() < 0 && cluster->mClu->detectorId() == 1 ) continue; + if ( projWCAL.mXYZ.X() > 0 && cluster->mClu->detectorId() == 0 ) continue; + + hdxWCAL->Fill( dx ); + hdyWCAL->Fill( dy ); + // printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); + hdrWCAL->Fill( dr ); + + hWCALX->Fill( cluster->mXYZ.X(), projWCAL.mXYZ.X() ); + hWCALY->Fill( cluster->mXYZ.Y(), projWCAL.mXYZ.Y() ); + } + + // loop over WCAL clusters + for ( int k = 0; k < hcal->GetEntries(); k++ ){ + FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)hcal->At(k); + double dx = projHCAL.mXYZ.X() - cluster->mXYZ.X(); + double dy = projHCAL.mXYZ.Y() - cluster->mXYZ.Y(); + double dr = sqrt( dx*dx + dy*dy ); + + hdxHCAL->Fill( dx ); + hdrHCAL->Fill( dr ); + } + + } +} + + +// Loop on events +void eventLoop( int numEventsLimit = -1, int reportEveryNthEvent = -1 ){ + int lastEventIndex = (numEventsLimit > 0 ? numEventsLimit : t->GetEntries() ); + for ( int i = 0; i < lastEventIndex; i++ ){ + t->GetEntry(i); + if ( reportEveryNthEvent > 0 && i % reportEveryNthEvent == 0){ + printf( "Processing Event %d...\n", i ); + } + // run qa subroutines here + // qaMomentumResolution(); + qaFCSTrackMatch(); + } +} + + + +void qa( TString filename = "fwdtree.root" ){ + setupRead( filename ); + TFile * fOut = new TFile( "QuickQA.root", "RECREATE" ); + fOut->cd(); + eventLoop(5000, 100); + fOut->Write(); + // writeHistograms(); + return; + //loop over the events + int nEvents = t->GetEntries(); + if (nEvents > 1000) nEvents = 1000; + for ( int i = 0; i < nEvents; i++ ){ + t->GetEntry(i); + for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ + StMuFwdTrack *track = fwdTracks->At(j); + printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); + + StMuFwdTrackProjection projWCAL; + track->getProjectionFor(kFcsWcalId, projWCAL); + printf("Projection @ WCAL: det=%d, x=%f, y=%f, z=%f\n", projWCAL.mDetId, projWCAL.mXYZ.X(), projWCAL.mXYZ.Y(), projWCAL.mXYZ.Z()); + + + StMuFwdTrackProjection projHCAL; + track->getProjectionFor(kFcsHcalId, projHCAL); + printf("Projection @ HCAL: det=%d, x=%f, y=%f, z=%f\n", projHCAL.mDetId, projHCAL.mXYZ.X(), projHCAL.mXYZ.Y(), projHCAL.mXYZ.Z()); + + // loop over WCAL clusters + for ( int k = 0; k < wcal->GetEntries(); k++ ){ + FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); + + printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); + + } + + + // loop over WCAL clusters + for ( int k = 0; k < wcal->GetEntries(); k++ ){ + FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); + + printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); + + } + + } + } + cout << "Processed: " << t->GetEntries() << " entries" << endl; +} diff --git a/StRoot/StFwdTrackMaker/macro/shell.C b/StRoot/StFwdTrackMaker/macro/shell.C new file mode 100755 index 00000000000..f5561a82137 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/shell.C @@ -0,0 +1,9 @@ + + + +void shell(){ + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("bfc.C"); + bfc(-1, "StEvent cmudst fwdTrack", ""); +} \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/close.C b/StRoot/StFwdTrackMaker/macro/sim/close.C new file mode 100755 index 00000000000..5ee794cf871 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/close.C @@ -0,0 +1,108 @@ +//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-50}','${3:-0.001}','${4:-0.001}','${5:-3.0}','${6:-0.004}','${7:-0}',"'${8:- }'")'; exit $? +// that is a valid shebang to run script as executable, but with only one arg + + +// Run very fast fwd tracking +// generate some input data using genfzd + +TFile *output = 0; + +void close( char *inFile = "sim.fzd", + int n = 100000, // nEvents to run + double primaryVertexSigmaXY = 0.001, + double primaryVertexSigmaZ = 0.001, + double fstRasterR = 3.0, + double fstRasterPhi = 0.0040906154, + int numFttToUse = 0, + TString note = "" + ) { + // report all of the parameters passed in + cout << "inFile = " << inFile << endl; + cout << "nEvents = " << n << endl; + TString mOutput = TString::Format( + "closure_PV_XY%dum_Z%dum_FST_R%.2fcm_PHI%0.3frad_NumFTT%d%s", + (int)(primaryVertexSigmaXY*1e4), + (int)(primaryVertexSigmaZ*1e4), + fstRasterR, + fstRasterPhi, + numFttToUse, + note.Data() + ); + // replace all "." with "p" in the output file name + mOutput.ReplaceAll(".", "p"); + mOutput += ".root"; + cout << "Output file = " << mOutput.Data() << endl; + + // Setup the chain for reading an FZD + TString _chain; + _chain = "fzin sdt20211016 MakeEvent bigbig evout cmudst tree"; + + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + gSystem->Load( "libStFttSimMaker" ); + gSystem->Load( "libStFcsTrackMatchMaker" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libStarGeneratorUtil" ); + + gSystem->Load("libXMLIO.so"); + gSystem->Load("libgenfit2.so"); + gSystem->Load("libKiTrack.so"); + gSystem->Load("StarGeneratorUtil"); + // gSystem->Load("libMathMore.so"); + gSystem->Load("StEventUtilities"); + gSystem->Load("StEpdUtil"); + gSystem->Load("StFwdTrackMaker"); + + gSystem->Load("StFwdUtils.so"); + + + // Configure the Forward Tracker + StFwdClosureMaker * fwdClosure = new StFwdClosureMaker(); + fwdClosure->SetDebug(1); + fwdClosure->mMaxIt = 4; + + fwdClosure->mBlowUp = 1e3; + fwdClosure->mPVal = 1e-3; + fwdClosure->mRelChi2 = 1e-3; + + fwdClosure->mFttMode = StFwdClosureMaker::kStrip; + + fwdClosure->mPrimaryVertexSigXY = primaryVertexSigmaXY; + fwdClosure->mPrimaryVertexSigZ = primaryVertexSigmaZ; + fwdClosure->mRasterR = fstRasterR; + fwdClosure->mRasterPhi = fstRasterPhi; + fwdClosure->mNumFttToUse = numFttToUse; + fwdClosure->mOutFile = mOutput; + fwdClosure->SetDebug(1); + + chain->AddBefore("MuDst", fwdClosure); + + + StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); + + // if (muDstMaker){ + // StFwdQAMaker *fwdQA = new StFwdQAMaker(); + // fwdQA->SetDebug(2); + // chain->AddAfter("MuDst", fwdQA); + // } + +chain_loop: + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + cout << "--------->START EVENT: " << i << endl; + chain->Clear(); + if (kStOK != chain->Make()) + break; + cout << "<---------- END EVENT" << endl; + } // event loop +} diff --git a/StRoot/StFwdTrackMaker/macro/sim/fast.C b/StRoot/StFwdTrackMaker/macro/sim/fast.C new file mode 100755 index 00000000000..7cfc9ba7357 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/fast.C @@ -0,0 +1,145 @@ +//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-5}')'; exit $? +// that is a valid shebang to run script as executable, but with only one arg + + +// Run very fast fwd tracking +// generate some input data using genfzd + +TFile *output = 0; + +void fast( char *inFile = "sim.fzd", + int n = 1000, // nEvents to run + bool useFstForSeedFinding = true, // use FTT (default) or FST for track finding + bool enableTrackRefit = true, // Enable track refit (default off) + bool realisticSim = true, // enables data-like mode, real track finding and fitting without MC seed + bool useZeroB = false + ) { + // report all of the parameters passed in + cout << "inFile = " << inFile << endl; + cout << "n = " << n << endl; + cout << "useFstForSeedFinding = " << useFstForSeedFinding << endl; + cout << "enableTrackRefit = " << enableTrackRefit << endl; + cout << "realisticSim = " << realisticSim << endl; + cout << "useZeroB = " << useZeroB << endl; + const char *geom = ""; + TString _geom = geom; + + // Switches for common options + bool SiIneff = false; + bool useConstBz = false; + bool useFCS = true; + + // to use the geom cache (skip agml build which is faster) + // set the _geom string to "" and make sure the cache file ("fGeom.root") is present + // _geom = ""; + + // Setup the chain for reading an FZD + TString _chain; + + _chain = Form("fzin %s sdt20211016 fwdTrack MakeEvent bigbig evout cmudst tree", _geom.Data() ); + + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + gSystem->Load( "libStFttSimMaker" ); + gSystem->Load( "libStFcsTrackMatchMaker" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libStarGeneratorUtil" ); + + + gSystem->Load("StFwdUtils.so"); + + + + // Configure the Forward Tracker + StFwdTrackMaker * fwdTrack = (StFwdTrackMaker*) chain->GetMaker( "fwdTrack" ); + + if ( fwdTrack ){ + fwdTrack->SetDebug(1); + // config file set here for ideal simulation + if (!realisticSim){ + cout << "Configured for ideal simulation (MC finding + MC mom seed)" << endl; + fwdTrack->setConfigForIdealSim( ); + } else { + cout << "Configured for realistic simulation" << endl; + fwdTrack->setConfigForRealisticSim( ); + cout << "Configured for realistic simulation DONE" << endl; + } + + if ( _geom == "" ){ + cout << "Using the Geometry cache: fGeom.root" << endl; + fwdTrack->setGeoCache( "fGeom.root" ); + } + + // choose + if (useFstForSeedFinding) + fwdTrack->setSeedFindingWithFst(); + else { // default for this true/false option + fwdTrack->setSeedFindingWithFtt(); + } + // other options + // fwdTrack->setSeedFindingWithFtt(); + // fwdTrack->setSeedFindingWithFstFttSequential(); + // fwdTrack->setSeedFindingWithFstFttSimultaneous(); + + + fwdTrack->setOutputFilename( TString::Format( "%s.output.root", inFile ).Data() ); + fwdTrack->SetVisualize( false ); + fwdTrack->SetDebug(); + fwdTrack->setTrackRefit( enableTrackRefit ); + fwdTrack->setConstB( useConstBz ); + + if ( useZeroB ){ + cout << "Setting B = 0" << endl; + fwdTrack->setZeroB( true ); + } + + bool doFitQA = true; + if ( doFitQA ){ + StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); + fwdFitQA->SetDebug(); + TString fitqaoutname(gSystem->BaseName(inFile)); + fitqaoutname.ReplaceAll(".fzd", ".FwdFitQA.root"); + fwdFitQA->setOutputFilename( fitqaoutname ); + chain->AddAfter("fwdTrack", fwdFitQA); + } + cout << "fwd tracker setup" << endl; + } + + StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); + + if (muDstMaker){ + StFwdQAMaker *fwdQA = new StFwdQAMaker(); + fwdQA->SetDebug(2); + TString fwdqaname(gSystem->BaseName(inFile)); + fwdqaname.ReplaceAll(".fzd", ".FwdTree.root"); + fwdQA->setTreeFilename(fwdqaname); + chain->AddAfter("MuDst", fwdQA); + } + + // The PicoDst + gSystem->Load("libStPicoEvent"); + gSystem->Load("libStPicoDstMaker"); + StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); + cout << "picoMk = " << picoMk << endl; + picoMk->setVtxMode(StPicoDstMaker::Default); + +chain_loop: + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + cout << "--------->START EVENT: " << i << endl; + chain->Clear(); + if (kStOK != chain->Make()) + break; + cout << "<---------- END EVENT" << endl; + } // event loop +} diff --git a/StRoot/StFwdTrackMaker/macro/sim/gen b/StRoot/StFwdTrackMaker/macro/sim/gen new file mode 100755 index 00000000000..d8629b8b188 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/gen @@ -0,0 +1,17 @@ +#!/usr/bin/bash + +nEvents=${1:-1000} #num events +pid=${2:-5} # default muon + +echo "Usage:\n sim/gen " +echo "nEvents=${nEvents}" + +strongrandom=`od -vAn -N3 -tu4 < /dev/urandom | tr -d '[:space:]'` + +if [ -f "sim.fzd" ] ; then + echo "sim.fzd already exists, skipping" +else + echo "strong random ${strongrandom}" + echo root4star -b -q -l 'sim/gen.C( '"${nEvents}"','"${strongrandom}"')' + time root4star -b -q -l 'sim/gen.C( '"${nEvents}"','"${strongrandom}"')' +fi diff --git a/StRoot/StFwdTrackMaker/macro/sim/gen.C b/StRoot/StFwdTrackMaker/macro/sim/gen.C old mode 100644 new mode 100755 index 5056662f861..b5d2b16ba43 --- a/StRoot/StFwdTrackMaker/macro/sim/gen.C +++ b/StRoot/StFwdTrackMaker/macro/sim/gen.C @@ -1,3 +1,4 @@ +//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? // macro to instantiate the Geant3 from within // STAR C++ framework and get the starsim prompt // To use it do @@ -18,7 +19,24 @@ StarKinematics *kinematics = 0; TH1F* hNumHits = 0; TString nameParticle = "mu+"; -float numParticles = 5; +int numParticles = 1; +float minPt = 0.0; +float maxPt = 1.0; +float minEta = 2.5; +float maxEta = 4.00; +float minPhi = 0.0; +float maxPhi = 2.0 * TMath::Pi(); + +float vtxX = 0.0; +float vtxY = 0.0; +float vtxZ = 0.0; + +float vtxSigmaX = 0.0001; +float vtxSigmaY = 0.0001; +float vtxSigmaZ = 0.0001; + +TString fzdFilename = "sim.fzd"; +TString primaryName = "sim.root"; // ---------------------------------------------------------------------------- void geometry( TString tag, Bool_t agml=true ) @@ -35,58 +53,46 @@ void command( TString cmd ) geant_maker -> Do( cmd ); } // ---------------------------------------------------------------------------- +void trig_event( Int_t i ) +{ + if ( gRandom->Rndm() > 0.5 ) { + nameParticle = "mu+"; + } else { + nameParticle = "mu-"; + } + kinematics->Kine( numParticles, nameParticle.Data(), minPt, maxPt, minEta, maxEta, minPhi, maxPhi ); +} +// ---------------------------------------------------------------------------- void trig( Int_t n=1 ) { - - for ( Int_t i=0; iClear(); - - kinematics->Kine( numParticles, nameParticle.Data(), 0.2, 5.0, 2.0, 4.50 ); - // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); - + trig_event( i ); // Generate the event chain->Make(); - - TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); - if ( hits ) { - double nhits = hits->GetNRows(); - hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); - std::cout << "N hits = " << nhits << std::endl; - } - - // Print the event - // command("gprint hits stgh"); - } } // ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- void Kinematics() { - + // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); gSystem->Load( "libKinematics.so"); kinematics = new StarKinematics(); - _primary->AddGenerator(kinematics); } // ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) -{ +void gen( Int_t nevents=1000, Int_t rngSeed=12352342 ) +{ - cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; + cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; gSystem->Load( "libStarRoot.so" ); gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); gROOT->ProcessLine(".L bfc.C"); { - TString simple = "sdt20211016 y2023 geant gstar usexgeom agml "; + TString simple = "sdt20211016 y2024 geant gstar usexgeom agml "; bfc(0, simple ); } @@ -96,7 +102,7 @@ void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) gSystem->Load( "StarGeneratorEvent.so" ); gSystem->Load( "StarGeneratorBase.so" ); - gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libMathMore.so" ); gSystem->Load( "xgeometry.so" ); // Setup RNG seed and map all ROOT TRandom here @@ -110,7 +116,7 @@ void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) // StarPrimaryMaker * _primary = new StarPrimaryMaker(); { - _primary -> SetFileName( "sim.root"); + _primary -> SetFileName( primaryName ); chain -> AddBefore( "geant", _primary ); } @@ -120,19 +126,15 @@ void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) // Initialize primary event generator and all sub makers // _primary -> Init(); - _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex - _primary->SetVertex(0.0, 0.0, 0.0 ); + _primary->SetSigma( vtxSigmaX, vtxSigmaY, vtxSigmaZ ); // 1mm x 1mm x 1mm smearing at the vertex + _primary->SetVertex(vtxX, vtxY, vtxZ ); // // Setup geometry and set starsim to use agusread for input // //geometry("y2012"); command("gkine -4 0"); - command("gfile o sim.fzd"); - - - hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); - // hNumHits->SetBit(TH1::kCanRebin); + command( TString::Format("gfile o %s", fzdFilename.Data()) ); // command( "DCAY 0" ); @@ -150,19 +152,14 @@ void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) // command( "MULS 0" ); // command( "STRA 0" ); // command( "physi" ); - + // // Trigger on nevents // + // StarMagField::setConstBz(true); trig( nevents ); - // TFile * f = new TFile( "gen.root", "RECREATE" ); - // f->cd(); - // hNumHits->Write(); - // f->Write(); - command("call agexit"); // Make sure that STARSIM exits properly } // ---------------------------------------------------------------------------- - diff --git a/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-fst-seed b/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-fst-seed new file mode 100755 index 00000000000..601b8f911aa --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-fst-seed @@ -0,0 +1,2 @@ +nEvents=${1:-10} #num events +root4star -b -q -l 'sim/sim.C('${nEvents}', "StFwdTrackMaker_ideal_sim_fst_seed.root", true, true, false )' >& LOG_IDEAL_SIM_FST_SEED.log \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-ftt-seed b/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-ftt-seed new file mode 100755 index 00000000000..2613cef1b98 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-ftt-seed @@ -0,0 +1,2 @@ +nEvents=${1:-10} #num events +root4star -b -q -l 'sim/sim.C('${nEvents}', "StFwdTrackMaker_ideal_sim_ftt_seed.root", false, true, false )' >& LOG_IDEAL_SIM_FTT_SEED.log \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/jpsi b/StRoot/StFwdTrackMaker/macro/sim/jpsi new file mode 100755 index 00000000000..656d73c0874 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/jpsi @@ -0,0 +1,16 @@ +#!/usr/bin/bash + +nEvents=${1:-10} #num events + +echo "Usage:\n sim/jpsi " +echo "nEvents=${nEvents}" + +strongrandom=`od -vAn -N3 -tu4 < /dev/urandom | tr -d '[:space:]'` + +if [ -f "jpsi.fzd" ] ; then + echo "jpsi.fzd already exists, skipping" +else + echo "strong random ${strongrandom}" + echo root4star -b -q -l 'sim/jpsi.C( '"${nEvents}"','"${strongrandom}"')' + time root4star -b -q -l 'sim/jpsi.C( '"${nEvents}"','"${strongrandom}"')' +fi diff --git a/StRoot/StFwdTrackMaker/macro/sim/jpsi.C b/StRoot/StFwdTrackMaker/macro/sim/jpsi.C new file mode 100755 index 00000000000..bc4f936d29e --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/jpsi.C @@ -0,0 +1,225 @@ +//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? +// macro to instantiate the Geant3 from within +// STAR C++ framework and get the starsim prompt +// To use it do +// root4star starsim.C + +class St_geant_Maker; +St_geant_Maker *geant_maker = 0; + +class StarGenEvent; +StarGenEvent *event = 0; + +class StarPrimaryMaker; +StarPrimaryMaker *_primary = 0; + +class StarKinematics; +StarKinematics *kinematics = 0; + + +TH1F* hMll = 0; +bool decayJPsiToElectrons = false; +float numParticles = 1; + +// ---------------------------------------------------------------------------- +void geometry( TString tag, Bool_t agml=true ) +{ + TString cmd = "DETP GEOM "; cmd += tag + " field=-5.0"; + if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); + geant_maker -> LoadGeometry(cmd); + // if ( agml ) command("gexec $STAR_LIB/libxgeometry.so"); +} +// ---------------------------------------------------------------------------- +void command( TString cmd ) +{ + if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); + geant_maker -> Do( cmd ); +} +// ---------------------------------------------------------------------------- +void trig( Int_t n=1 ) +{ + + + for ( Int_t i=0; iClear(); + + //(Momentum, Energy units are Gev/C, GeV) + Double_t masses[2] = { 0.00051099895000, 0.00051099895000} ; + + if (!decayJPsiToElectrons){ + masses[0] = 0.1056583755; + masses[1] = 0.1056583755; + } + + TGenPhaseSpace genEvent; + TLorentzVector W; + // W.SetPtEtaPhiM( 0.0, 100.0, 0, 3.096 ); + W.SetXYZM( 0, 0, 30, 3.096 ); + genEvent.SetDecay(W, 2, masses); + + TLorentzVector lv; + for ( int j = 0; j < numParticles; j++ ){ + Double_t weight = genEvent.Generate(); + TLorentzVector *pElectron = genEvent.GetDecay(0); + TLorentzVector *pPositron = genEvent.GetDecay(1); + lv = *pElectron + *pPositron; + + StarGenParticle *ele; + if ( decayJPsiToElectrons ) + ele = kinematics->AddParticle( "e-" ); + else + ele = kinematics->AddParticle( "mu-" ); + ele->SetPx(pElectron->Px()); + ele->SetPy(pElectron->Py()); + ele->SetPz(pElectron->Pz()); + ele->SetMass( masses[0] ); + + StarGenParticle *pos; + if ( decayJPsiToElectrons ) + pos = kinematics->AddParticle( "e+" ); + else + pos = kinematics->AddParticle( "mu+" ); + pos->SetPx(pPositron->Px()); + pos->SetPy(pPositron->Py()); + pos->SetPz(pPositron->Pz()); + pos->SetMass( masses[0] ); + + hMll->Fill( lv.M() ); + + cout << "ele eta = " << pElectron->Eta() << endl; + cout << "pos eta = " << pPositron->Eta() << endl; + } + + + // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); + + // Generate the event + chain->Make(); + + // TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); + // if ( hits ) { + // double nhits = hits->GetNRows(); + // hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); + // std::cout << "N hits = " << nhits << std::endl; + // } + + // Print the event + // command("gprint hits stgh"); + + } +} +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void Kinematics() +{ + + // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); + gSystem->Load( "libKinematics.so"); + kinematics = new StarKinematics(); + + _primary->AddGenerator(kinematics); +} +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void jpsi( Int_t nevents=10000, Int_t rngSeed=12352342, bool decayToElectrons = true ) +{ + + hMll = new TH1F("hMll",";Mll;counts [10MeV]", 200, 2.0, 4.0 ); + decayJPsiToElectrons = decayToElectrons; + cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; + if ( decayToElectrons ){ + cout << "Simulating J/psi->e+e-" << endl; + } else { + cout << "Simulating J/psi->mu+mu-" << endl; + } + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + + gROOT->ProcessLine(".L bfc.C"); + { + TString simple = "sdt20211016 y2024 geant gstar usexgeom agml "; + bfc(0, simple ); + } + + gSystem->Load( "libVMC.so"); + + gSystem->Load( "StarGeneratorUtil.so" ); + gSystem->Load( "StarGeneratorEvent.so" ); + gSystem->Load( "StarGeneratorBase.so" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "xgeometry.so" ); + + + + // Setup RNG seed and map all ROOT TRandom here + StarRandom::seed( rngSeed ); + StarRandom::capture(); + + // + // Create the primary event generator and insert it + // before the geant maker + // + // StarPrimaryMaker * + _primary = new StarPrimaryMaker(); + { + _primary -> SetFileName( "jpsi.root"); + chain -> AddBefore( "geant", _primary ); + } + + Kinematics(); + + // + // Initialize primary event generator and all sub makers + // + _primary -> Init(); + _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex + _primary->SetVertex(0.0, 0.0, 0.0 ); + + // + // Setup geometry and set starsim to use agusread for input + // + //geometry("y2012"); + command("gkine -4 0"); + command("gfile o jpsi.fzd"); + + + hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); + // hNumHits->SetBit(TH1::kCanRebin); + + + // command( "DCAY 0" ); + // command( "ANNI 0" ); + // command( "BREM 0" ); + // command( "COMP 0" ); + // command( "HADR 0" ); + // command( "MUNU 0" ); + // command( "PAIR 0" ); + // command( "PFIS 0" ); + // command( "PHOT 0" ); + // command( "RAYL 0" ); + // command( "LOSS 4" ); + // command( "DRAY 0" ); + // command( "MULS 0" ); + // command( "STRA 0" ); + // command( "physi" ); + + // + // Trigger on nevents + // + trig( nevents ); + + TFile * f = new TFile( "jpsi_gen.root", "RECREATE" ); + f->cd(); + hMll->Write(); + f->Write(); + + command("call agexit"); // Make sure that STARSIM exits properly + +} +// ---------------------------------------------------------------------------- + diff --git a/StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C b/StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C new file mode 100644 index 00000000000..233a0d37a91 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C @@ -0,0 +1,181 @@ +//usr/bin/env root4star -l -b -q $0'('$1')'; exit $? +// that is a valid shebang to run script as executable, but with only one arg + + +// Run very fast fwd tracking +// generate some input data using genfzd + +TFile *output = 0; + +void jpsi_ana( int n = 5, // nEvents to run + string outputName = "stFwdTrackMaker_ideal_jpsi.root", + bool useFstForSeedFinding = false, // use FTT (default) or FST for track finding + bool enableTrackRefit = true, // Enable track refit (default off) + bool realisticSim = false, // enables data-like mode, real track finding and fitting without MC seed + char *inFile = "jpsi.fzd" + ) { + cout << "Running " << n << " events from " << inFile << endl; + const char *geom = "y2023"; + TString _geom = geom; + + // Switches for common options + bool SiIneff = false; + bool useConstBz = false; + bool useFCS = true; + + + // Setup the chain for reading an FZD + TString _chain; + if ( useFCS ) + _chain = Form("fzin %s sdt20211016 fstFastSim fcsSim fcsWFF fcsCluster fwdTrack MakeEvent StEvent ReverseField agml usexgeom bigbig evout cmudst tree", _geom.Data()); + else + _chain = Form("fzin %s sdt20211016 MakeEvent StEvent ReverseField agml usexgeom bigbig fstFastSim fcsSim fwdTrack evout cmudst tree", _geom.Data()); + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + if ( useConstBz ) + StarMagField::setConstBz(true); + + gSystem->Load( "libStFttSimMaker" ); + gSystem->Load( "libStFcsTrackMatchMaker" ); + + // FCS setup, if included + if (useFCS) { + + StFcsDbMaker* fcsdbmkr = (StFcsDbMaker*) chain->GetMaker("fcsDbMkr"); + cout << "fcsdbmkr="<GetDataSet("fcsDb"); + cout << "fcsdb="<setDbAccess(1); + + // Configure FCS simulator + StFcsFastSimulatorMaker *fcssim = (StFcsFastSimulatorMaker*) chain->GetMaker("fcsSim"); + fcssim->setDebug(1); + //fcssim->setLeakyHcal(0); + + StFcsWaveformFitMaker *fcsWFF= (StFcsWaveformFitMaker*) chain->GetMaker("StFcsWaveformFitMaker"); + fcsWFF->setEnergySelect(0); + + StFcsClusterMaker *fcsclu = (StFcsClusterMaker*) chain->GetMaker("StFcsClusterMaker"); + fcsclu->setDebug(1); + } + + // { + gSystem->Load("StFwdUtils.so"); + // StFwdJPsiMaker *fwdJPsi = new StFwdJPsiMaker(); + // fwdJPsi->SetDebug(); + // chain->AddMaker(fwdJPsi); + // goto chain_loop; + // } + + + // Configure FST FastSim + TString qaoutname(gSystem->BaseName(inFile)); + qaoutname.ReplaceAll(".fzd", ".FastSimu.QA.root"); + StFstFastSimMaker *fstFastSim = (StFstFastSimMaker*) chain->GetMaker( "fstFastSim" );; + + if (SiIneff) + fstFastSim->SetInEfficiency(0.1); // inefficiency of Si + + fstFastSim->SetQAFileName(qaoutname); + + cout << "Adding StFstFastSimMaker to chain" << endl; + chain->AddMaker(fstFastSim); + + + // Configure the Forward Tracker + StFwdTrackMaker * fwdTrack = (StFwdTrackMaker*) chain->GetMaker( "fwdTrack" ); + + // config file set here for ideal simulation + if (!realisticSim){ + cout << "Configured for ideal simulation (MC finding + MC mom seed)" << endl; + fwdTrack->setConfigForIdealSim( ); + } else { + cout << "Configured for realistic simulation" << endl; + fwdTrack->setConfigForRealisticSim( ); + cout << "Configured for realistic simulation DONE" << endl; + } + + if (useFstForSeedFinding) + fwdTrack->setSeedFindingWithFst(); + else + fwdTrack->setSeedFindingWithFtt(); + + fwdTrack->setTrackRefit( enableTrackRefit ); + fwdTrack->setOutputFilename( outputName ); + fwdTrack->SetGenerateTree( true ); + fwdTrack->SetGenerateHistograms( true ); + fwdTrack->SetDebug(); + + cout << "fwd tracker setup" << endl; + + + if (!useFCS){ + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(); + chain->AddAfter("fwdTrack", fwdAna); + } + + StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); + if (useFCS) { + // FwdTrack and FcsCluster assciation + gSystem->Load("StFcsTrackMatchMaker"); + StFcsTrackMatchMaker *match = new StFcsTrackMatchMaker(); + match->setMaxDistance(6,10); + match->setFileName("fcstrk.root"); + match->SetDebug(); + chain->AddMaker(match); + + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(); + chain->AddAfter("FcsTrkMatch", fwdAna); + + StFwdJPsiMaker *fwdJPsi = new StFwdJPsiMaker(); + fwdJPsi->SetDebug(); + chain->AddAfter("FcsTrkMatch", fwdJPsi); + + gSystem->Load("StFcsDiLeptonMaker"); + StFcsDiLeptonMaker *dilep = new StFcsDiLeptonMaker; + //TString dilepfile(outfile); dilepfile.ReplaceAll(".root",".dilep.root"); + dilep->setFileName("dilep.root");//dilepfile.Data()); + //chain->AddAfter("FcsTrkMatch", dilep); + + // Produce MuDst output + chain->AddAfter( "FcsTrkMatch", muDstMaker ); + } else { + chain->AddAfter( "fwdAna", muDstMaker ); + } + + + +chain_loop: + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + + cout << "--------->START EVENT: " << i << endl; + + chain->Clear(); + if (kStOK != chain->Make()) + break; + + + // StMuDst * mds = muDstMaker->muDst(); + // StMuFwdTrackCollection * ftc = mds->muFwdTrackCollection(); + // cout << "Number of StMuFwdTracks: " << ftc->numberOfFwdTracks() << endl; + // for ( size_t iTrack = 0; iTrack < ftc->numberOfFwdTracks(); iTrack++ ){ + // StMuFwdTrack * muFwdTrack = ftc->getFwdTrack( iTrack ); + // cout << "muFwdTrack->mPt = " << muFwdTrack->momentum().Pt() << endl; + + // } + + cout << "<---------- END EVENT" << endl; + } // event loop +} diff --git a/StRoot/StFwdTrackMaker/macro/sim/lambda.C b/StRoot/StFwdTrackMaker/macro/sim/lambda.C new file mode 100755 index 00000000000..23af6349857 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/lambda.C @@ -0,0 +1,191 @@ +//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? +// macro to instantiate the Geant3 from within +// STAR C++ framework and get the starsim prompt +// To use it do +// root4star starsim.C + +class St_geant_Maker; +St_geant_Maker *geant_maker = 0; + +class StarGenEvent; +StarGenEvent *event = 0; + +class StarPrimaryMaker; +StarPrimaryMaker *_primary = 0; + +class StarKinematics; +StarKinematics *kinematics = 0; + + +TH1F* hMll = 0; +float numParticles = 1; + +// ---------------------------------------------------------------------------- +void geometry( TString tag, Bool_t agml=true ) +{ + TString cmd = "DETP GEOM "; cmd += tag + " field=-5.0"; + if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); + geant_maker -> LoadGeometry(cmd); + // if ( agml ) command("gexec $STAR_LIB/libxgeometry.so"); +} +// ---------------------------------------------------------------------------- +void command( TString cmd ) +{ + if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); + geant_maker -> Do( cmd ); +} +// ---------------------------------------------------------------------------- +void trig( Int_t n=1 ) +{ + + + for ( Int_t i=0; iClear(); + + //(Momentum, Energy units are Gev/C, GeV) + Double_t masses[2] = { 0.13957, 0.938} ; + + TGenPhaseSpace genEvent; + TLorentzVector W; + // W.SetPtEtaPhiM( 0.0, 100.0, 0, 3.096 ); + W.SetXYZM( 0, 0, 5, 1.11568 ); + genEvent.SetDecay(W, 2, masses); + + TLorentzVector lv; + for ( int j = 0; j < numParticles; j++ ){ + Double_t weight = genEvent.Generate(); + TLorentzVector *pPion = genEvent.GetDecay(0); + TLorentzVector *pProton = genEvent.GetDecay(1); + lv = *pPion + *pProton; + + StarGenParticle *pion; + pion = kinematics->AddParticle( "pi-" ); + + pion->SetPx(pPion->Px()); + pion->SetPy(pPion->Py()); + pion->SetPz(pPion->Pz()); + pion->SetMass( masses[0] ); + + StarGenParticle *proton; + proton = kinematics->AddParticle( "p" ); + + + proton->SetPx(pProton->Px()); + proton->SetPy(pProton->Py()); + proton->SetPz(pProton->Pz()); + proton->SetMass( masses[1] ); + + hMll->Fill( lv.M() ); + + cout << "pion eta = " << pPion->Eta() << endl; + cout << "proton eta = " << pProton->Eta() << endl; + } + + + // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); + + // Generate the event + chain->Make(); + + // TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); + // if ( hits ) { + // double nhits = hits->GetNRows(); + // hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); + // std::cout << "N hits = " << nhits << std::endl; + // } + + // Print the event + // command("gprint hits stgh"); + + } +} +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void Kinematics() +{ + + // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); + gSystem->Load( "libKinematics.so"); + kinematics = new StarKinematics(); + + _primary->AddGenerator(kinematics); +} +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void lambda( Int_t nevents=100, Int_t rngSeed=12352342 ) +{ + hMll = new TH1F("hMll",";Mll;counts [10MeV]", 200, 2.0, 4.0 ); + cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; + cout << "Simulating J/psi->e+e-" << endl; + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + + gROOT->ProcessLine(".L bfc.C"); + { + TString simple = "sdt20211016 y2023 geant gstar usexgeom agml "; + bfc(0, simple ); + } + + gSystem->Load( "libVMC.so"); + + gSystem->Load( "StarGeneratorUtil.so" ); + gSystem->Load( "StarGeneratorEvent.so" ); + gSystem->Load( "StarGeneratorBase.so" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "xgeometry.so" ); + + // Setup RNG seed and map all ROOT TRandom here + StarRandom::seed( rngSeed ); + StarRandom::capture(); + + // + // Create the primary event generator and insert it + // before the geant maker + // + // StarPrimaryMaker * + _primary = new StarPrimaryMaker(); + { + _primary -> SetFileName( "lambda_fwd_gun.root"); + chain -> AddBefore( "geant", _primary ); + } + + Kinematics(); + + // + // Initialize primary event generator and all sub makers + // + _primary -> Init(); + _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex + _primary->SetVertex(0.0, 0.0, 0.0 ); + + // + // Setup geometry and set starsim to use agusread for input + // + //geometry("y2012"); + command("gkine -4 0"); + command("gfile o lambda_fwd_gun.fzd"); + + + hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); + + // + // Trigger on nevents + // + trig( nevents ); + + TFile * f = new TFile( "lambda_gen.root", "RECREATE" ); + f->cd(); + hMll->Write(); + f->Write(); + + command("call agexit"); // Make sure that STARSIM exits properly + +} +// ---------------------------------------------------------------------------- + diff --git a/StRoot/StFwdTrackMaker/macro/sim/real-sim-fst-seed b/StRoot/StFwdTrackMaker/macro/sim/real-sim-fst-seed new file mode 100755 index 00000000000..6c970f1336b --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/real-sim-fst-seed @@ -0,0 +1,2 @@ +nEvents=${1:-10} #num events +root4star -b -q -l 'sim/sim.C('${nEvents}', "StFwdTrackMaker_real_sim_fst_seed.root", true, true, true )' >& LOG_REAL_SIM_FST_SEED.log \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/real-sim-ftt-seed b/StRoot/StFwdTrackMaker/macro/sim/real-sim-ftt-seed new file mode 100755 index 00000000000..f66a71321bd --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/real-sim-ftt-seed @@ -0,0 +1,2 @@ +nEvents=${1:-10} #num events +root4star -b -q -l 'sim/sim.C('${nEvents}', "StFwdTrackMaker_real_sim_ftt_seed.root", false, true, true )' >& LOG_REAL_SIM_FTT_SEED.log \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/sim.C b/StRoot/StFwdTrackMaker/macro/sim/sim.C new file mode 100755 index 00000000000..beef7dfeb16 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/sim.C @@ -0,0 +1,242 @@ +//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-2000}')'; exit $? +// that is a valid shebang to run script as executable, but with only one arg + + +// Run very fast fwd tracking +// generate some input data using genfzd + +TFile *output = 0; + +void sim( char *inFile = "sim.fzd", + int n = 100, // nEvents to run + bool useFstForSeedFinding = true, // use FTT (default) or FST for track finding + bool enableTrackRefit = true, // Enable track refit (default off) + bool realisticSim = true, // enables data-like mode, real track finding and fitting without MC seed + bool useZeroB = false + ) { + // report all of the parameters passed in + cout << "inFile = " << inFile << endl; + cout << "n = " << n << endl; + cout << "useFstForSeedFinding = " << useFstForSeedFinding << endl; + cout << "enableTrackRefit = " << enableTrackRefit << endl; + cout << "realisticSim = " << realisticSim << endl; + cout << "useZeroB = " << useZeroB << endl; + const char *geom = "y2024 agml usexgeom"; + TString _geom = geom; + + // Switches for common options + bool SiIneff = false; + bool useConstBz = false; + bool useFCS = true; + + // use cached + _geom = ""; + + // to use the geom cache (skip agml build which is faster) + // set the _geom string to "" and make sure the cache file ("fGeom.root") is present + // _geom = ""; + + // Setup the chain for reading an FZD + TString _chain; + if ( useFCS ) + _chain = Form("fzin %s sdt20211016 fstFastSim fcsSim fcsWFF fcsCluster fwdTrack MakeEvent StEvent McEvent ReverseField bigbig evout cmudst tree", _geom.Data() ); + else + _chain = Form("fzin %s sdt20211016 MakeEvent StEvent ReverseField bigbig fstFastSim fcsSim fwdTrack evout cmudst tree", _geom.Data()); + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + if ( useConstBz ) + StarMagField::setConstBz(true); + + gSystem->Load( "libStFttSimMaker" ); + gSystem->Load( "libStFcsTrackMatchMaker" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libStarGeneratorUtil" ); + + StFttFastSimMaker * fttSim = new StFttFastSimMaker(); + fttSim->SetDebug(); + chain->AddAfter("fcsSim", fttSim); + + // FCS setup, if included + if (useFCS) { + + StFcsDbMaker* fcsdbmkr = (StFcsDbMaker*) chain->GetMaker("fcsDbMkr"); + cout << "fcsdbmkr="<GetDataSet("fcsDb"); + fcsdb->forceFixGain(); + fcsdb->forceFixGainCorrection(); + cout << "fcsdb="<setDbAccess(1); + + // Configure FCS simulator + StFcsFastSimulatorMaker *fcssim = (StFcsFastSimulatorMaker*) chain->GetMaker("fcsSim"); + fcssim->setDebug(1); + //fcssim->setLeakyHcal(0); + + StFcsWaveformFitMaker *fcsWFF= (StFcsWaveformFitMaker*) chain->GetMaker("StFcsWaveformFitMaker"); + fcsWFF->setEnergySelect(0); + + StFcsClusterMaker *fcsclu = (StFcsClusterMaker*) chain->GetMaker("StFcsClusterMaker"); + fcsclu->setDebug(1); + } + + // { + gSystem->Load("StFwdUtils.so"); + // StFwdJPsiMaker *fwdJPsi = new StFwdJPsiMaker(); + // fwdJPsi->SetDebug(); + // chain->AddMaker(fwdJPsi); + // goto chain_loop; + // } + + + // Configure FST FastSim + TString qaoutname(gSystem->BaseName(inFile)); + qaoutname.ReplaceAll(".fzd", ".FastSimu.QA.root"); + StFstFastSimMaker *fstFastSim = (StFstFastSimMaker*) chain->GetMaker( "fstFastSim" );; + + if (SiIneff) + fstFastSim->SetInEfficiency(0.1); // inefficiency of Si + + fstFastSim->SetQAFileName(qaoutname); + + cout << "Adding StFstFastSimMaker to chain" << endl; + chain->AddAfter("fcsSim", fstFastSim); + + + // Configure the Forward Tracker + StFwdTrackMaker * fwdTrack = (StFwdTrackMaker*) chain->GetMaker( "fwdTrack" ); + + if ( fwdTrack ){ + fwdTrack->SetDebug(1); + // config file set here for ideal simulation + if (!realisticSim){ + cout << "Configured for ideal simulation (MC finding + MC mom seed)" << endl; + fwdTrack->setConfigForIdealSim( ); + } else { + cout << "Configured for realistic simulation" << endl; + fwdTrack->setConfigForRealisticSim( ); + cout << "Configured for realistic simulation DONE" << endl; + } + + if ( _geom == "" ){ + cout << "Using the Geometry cache: fGeom.root" << endl; + fwdTrack->setGeoCache( "fGeom.root" ); + } + + // choose + if (useFstForSeedFinding) + fwdTrack->setSeedFindingWithFst(); + else { // default for this true/false option + fwdTrack->setSeedFindingWithFtt(); + } + // other options + // fwdTrack->setSeedFindingWithFtt(); + // fwdTrack->setSeedFindingWithFstFttSequential(); + // fwdTrack->setSeedFindingWithFstFttSimultaneous(); + + fwdTrack->setTrackRefit( enableTrackRefit ); + fwdTrack->setConstB( useConstBz ); + fwdTrack->setOutputFilename( TString::Format( "%s.output.root", inFile ).Data() ); + fwdTrack->SetVisualize( false ); + fwdTrack->SetDebug(); + fwdTrack->setIncludePrimaryVertexInFit( false ); + + // fwdTrack->setTrackFittingOff(); + // fwdTrack->setUseMcSeedForFit(true); + // fwdTrack->setConfigKeyValue("") + if ( useZeroB ){ + cout << "Setting B = 0" << endl; + fwdTrack->setZeroB( true ); + } + bool doFitQA = true; + if ( doFitQA ){ + StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); + fwdFitQA->SetDebug(); + TString fitqaoutname(gSystem->BaseName(inFile)); + fitqaoutname.ReplaceAll(".fzd", ".FwdFitQA.root"); + fwdFitQA->setOutputFilename( fitqaoutname ); + chain->AddAfter("fwdTrack", fwdFitQA); + } + cout << "fwd tracker setup" << endl; + } + + bool doFwdAna = true; + if (!useFCS && doFwdAna ){ + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(); + chain->AddAfter("fwdTrack", fwdAna); + } + + + StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); + if (useFCS) { + // FwdTrack and FcsCluster assciation + gSystem->Load("StFcsTrackMatchMaker"); + StFcsTrackMatchMaker *match = new StFcsTrackMatchMaker(); + match->setMaxDistance(6,10); + match->setFileName("fcstrk.root"); + match->SetDebug(); + chain->AddMaker(match); + + if ( doFwdAna ){ + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(); + chain->AddAfter("FcsTrkMatch", fwdAna); + } + + // Produce MuDst output + if ( muDstMaker ) + chain->AddAfter( "FcsTrkMatch", muDstMaker ); + } else { + if ( muDstMaker ) + chain->AddAfter( "fwdAna", muDstMaker ); + } + + if (muDstMaker){ + StFwdQAMaker *fwdQA = new StFwdQAMaker(); + fwdQA->SetDebug(2); + TString fwdqaname(gSystem->BaseName(inFile)); + fwdqaname.ReplaceAll(".fzd", ".FwdTree.root"); + fwdQA->setTreeFilename(fwdqaname); + chain->AddAfter("MuDst", fwdQA); + } + + // The PicoDst + gSystem->Load("libStPicoEvent"); + gSystem->Load("libStPicoDstMaker"); + StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); + cout << "picoMk = " << picoMk << endl; + picoMk->setVtxMode(StPicoDstMaker::Default); + + +chain_loop: + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + + cout << "--------->START EVENT: " << i << endl; + + chain->Clear(); + if (kStOK != chain->Make()) + break; + + + // StMuDst * mds = muDstMaker->muDst(); + // StMuFwdTrackCollection * ftc = mds->muFwdTrackCollection(); + // cout << "Number of StMuFwdTracks: " << ftc->numberOfFwdTracks() << endl; + // for ( size_t iTrack = 0; iTrack < ftc->numberOfFwdTracks(); iTrack++ ){ + // StMuFwdTrack * muFwdTrack = ftc->getFwdTrack( iTrack ); + // cout << "muFwdTrack->mPt = " << muFwdTrack->momentum().Pt() << endl; + + // } + cout << "<---------- END EVENT" << endl; + } // event loop +} diff --git a/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C b/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C new file mode 100755 index 00000000000..ac8339cb399 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C @@ -0,0 +1,28 @@ +//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? +#include "gen.C" +#include "TString.h" + +void single_particle_gun( Int_t nevents=5000, Int_t rngSeed=541522, + TString particle="mu-", Int_t nParticles=1, + Float_t _minPt=0.1, Float_t _maxPt=1.0, + Float_t _minEta=2.5, Float_t _maxEta=4.0, + Float_t _minPhi=0.0, Float_t _maxPhi=2.0*TMath::Pi() + ) +{ + nameParticle = particle; + numParticles = nParticles; + minPt = _minPt; + maxPt = _maxPt; + minEta = _minEta; + maxEta = _maxEta; + minPhi = _minPhi; + maxPhi = _maxPhi; + + TString safeName = particle; + safeName.ReplaceAll("+", "plus"); + safeName.ReplaceAll("-", "minus"); + fzdFilename = TString::Format("single_particle_gun_%s_%dEvents_%dPerEvent_Pt_%0.2fto%0.2f_Eta_%0.2fto%0.2f_Phi_%0.2fto%0.2f.fzd", safeName.Data(), nevents, numParticles, minPt, maxPt, minEta, maxEta, minPhi, maxPhi); + primaryName = TString::Format("single_particle_gun_%s_%dEvents_%dPerEvent_Pt_%0.2fto%0.2f_Eta_%0.2fto%0.2f_Phi_%0.2fto%0.2f.root", safeName.Data(), nevents, numParticles, minPt, maxPt, minEta, maxEta, minPhi, maxPhi); + cout << "Writing output to: " << fzdFilename << endl; + gen( nevents, rngSeed ); +} diff --git a/StRoot/StFwdTrackMaker/macro/viz.C b/StRoot/StFwdTrackMaker/macro/viz.C old mode 100644 new mode 100755 index 2768834e087..db0d6e33f60 --- a/StRoot/StFwdTrackMaker/macro/viz.C +++ b/StRoot/StFwdTrackMaker/macro/viz.C @@ -1,9 +1,9 @@ +//usr/bin/env root -l -b -q $0'('$1')'; exit $? #include "TFile.h" #include "TH1F.h" #include "TH2F.h" #include "TTree.h" - TFile * fData; TTree * fwd; TH2 * hFrame; @@ -247,7 +247,7 @@ void viz_points(const char* name, const char* cmd, int color, int eventIndex, Pr //add function for seed finding-AGE void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType projType = kRZSigned){ - fwd->Draw( "reco.id", "", "goff", 1, eventIndex ); + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); int nTrks = fwd->GetSelectedRows(); TLine line; @@ -256,7 +256,7 @@ void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType TLine proj; for (int i = 0; i < nTrks; i++){ //loop over number of tracks - fwd->Draw( TString::Format("reco[%d].projs.mXYZ.fX:reco[%d].projs.mXYZ.fY:reco[%d].projs.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); + fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); auto nHits = fwd->GetSelectedRows(); auto projX = fwd->GetV1(); auto projY = fwd->GetV2(); @@ -290,7 +290,35 @@ void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType line.SetLineColor(1); }*/ - line.DrawLine(x0, y0, x1, y1); + +void viz_tracks(int nTrk, int eventIndex, ProjectionType projType, bool seeds = false, int iTrack = -1, bool filter = false){ + TLine ll; + ll.SetLineWidth(lineScale); + + // ll.DrawLine( 150, 10, 250, 20 ); + // Tracks + int NumTracksFound = 0; + for ( int i = 0; i < nTrk; i++ ){ + if ( iTrack >= 0 && i != iTrack ) continue; + + // fwd->Draw( TString::Format("reco[%d].projs.mXYZ.fX:reco[%d].projs.mXYZ.fY:reco[%d].projs.mXYZ.fZ", i, i, i), TString::Format("reco[%d].status>=1 && fabs(reco[%d].mChi2) > 0.5", i, i), "goff", 1, eventIndex ); + fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ:reco[%d].mChi2:reco[%d].mDidFitConverge:reco[%d].mCharge", i, i, i, i, i, i), "", "goff", 1, eventIndex ); + // fwd->Draw( TString::Format("0:5:reco[%d].projs.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); + auto trkX = fwd->GetV1(); + auto trkY = fwd->GetV2(); + auto trkZ = fwd->GetV3(); + auto trkChi2 = fwd->GetV4(); + auto trkConv = fwd->GetVal(4); + auto trkQ = fwd->GetVal(5); + + TText text; + text.SetTextFont(43); + text.SetTextSize(36); + if (iTrack >= 0){ + text.DrawTextNDC( 0.05, 0.7, TString::Format( "chi2=%f", trkChi2[0] ) ); + text.DrawTextNDC( 0.05, 0.65, TString::Format( "converge=%d", trkConv[0] ) ); + }else { + // if ( trkChi2[0] > 100 ) continue; } } @@ -300,7 +328,7 @@ void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType void viz_proj( int eventIndex, ProjectionType projType = kRZSigned, bool markers = false ){ //get number of tracks - fwd->Draw( "reco.id", "", "goff", 1, eventIndex); //check if this is correct data to use to get nTrks + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex); //check if this is correct data to use to get nTrks int nTrks = fwd->GetSelectedRows(); //create line for track @@ -351,26 +379,45 @@ void viz_proj( int eventIndex, ProjectionType projType = kRZSigned, bool markers } } } - if (markers){ - //add marker to the legend - TText *t = new TText(.5,.5,"Hello World !"); - t->SetTextColor(kBlack); - t->SetTextFont(43); - t->SetTextSize(20); - //make this more functional? - if ( projType == kRZSigned ){ - LegendY = 5; - } else if (projType == kXY ){ - LegendY = -15; - } - TMarker *mk1 = new TMarker( LegendX, LegendY, 23 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColor( 2 ); - mk1->Draw("same"); - t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "Projected Hits ") ); - } - -} //end of fn + + if (seeds == false) return; + + for ( int i = 0; i < nTrk; i++ ){ + if ( iTrack >= 0 && i != iTrack ) continue; + + fwd->Draw( TString::Format("reco[%d].seeds.pos.fX:reco[%d].seeds.pos.fY:reco[%d].seeds.pos.fZ", i, i, i), TString::Format("reco[%d].mDidFitConverge!=0", i), "goff", 1, eventIndex ); + auto seedX = fwd->GetV1(); + auto seedY = fwd->GetV2(); + auto seedZ = fwd->GetV3(); + + // printf( "Found %d seeds for track %d\n", fwd->GetSelectedRows(), i ); + // int slc = TColor::GetColorPalette(i*100 % 255); + ll.SetLineColor(kGreen); + + for ( int j = 0; j < fwd->GetSelectedRows()-1; j++ ){ + + float seedX1 = xx( seedX[j], seedY[j], seedZ[j], projType ); + float seedY1 = yy( seedX[j], seedY[j], seedZ[j], projType ); + + // printf( "seed(x=%f, y=%f, z=%)->(xx=%f, yy=%f)\n", seedX[j], seedY[j], seedZ[j], seedX1, seedY1 ); + + float seedX2 = xx( seedX[j+1], seedY[j+1], seedZ[j+1], projType ); + float seedY2 = yy( seedX[j+1], seedY[j+1], seedZ[j+1], projType ); + + // printf( "(%f, %f) -> (%f, %f)\n", seedX1, seedY1, seedX2, seedY2 ); + ll.DrawLine( seedX1, seedY1, seedX2, seedY2 ); + + TMarker *mk1 = new TMarker( seedX1, seedY1, 20 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColor(kBlue); + mk1->Draw("same"); + + TMarker *mk2 = new TMarker( seedX2, seedY2, 20 ); + mk2->SetMarkerSize( 2.5 ); + mk2->SetMarkerColor(kBlue); + mk2->Draw("same"); + } // end loop j + } // end loop i //add function to compare lines @@ -395,7 +442,7 @@ void viz_stats( int eventIndex ){ fwd->Draw( "fcsX:fcsY:fcsZ", "", "goff", 1, eventIndex ); int numEpd = fwd->GetSelectedRows();*/ - fwd->Draw( "reco.id", "", "goff", 1, eventIndex ); + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); int numTracks = fwd->GetSelectedRows(); fwd->Draw( "fst.pos.fX:fst.pos.fY:fst.pos.fZ", "", "goff", 1, eventIndex ); int numFst = fwd->GetSelectedRows(); @@ -422,12 +469,21 @@ void viz_stats( int eventIndex ){ text.DrawTextNDC( 0.05, statTextY, TString::Format("WCal Clusters : %d", numWcal) ); n(); text.DrawTextNDC( 0.05, statTextY, TString::Format("HCal Clusters : %d", numHcal) ); n(); - //print reco statistics - /*fwd->Draw( "reco.reco.projs.mXYZ:fX:reco.reco.projs.mXYZ:fY:reco.reco.projs.mXYZ:fZ", "", "goff", 1, eventIndex ); - int numReco = fwd->GetSelectedRows(); - statTextY = 0.92; - text.DrawTextNDC( 0.35, statTextY, TString::Format("Reco Hits : %d", numReco) ); n();*/ + fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, eventIndex ); + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Tracks : %d", fwd->GetSelectedRows()) ); n(); + + fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100", "goff", 1, eventIndex ); + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); + + fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100 && reco.mCharge==1", "goff", 1, eventIndex ); + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Pos Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); + fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100 && reco.mCharge==-1", "goff", 1, eventIndex ); + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Neg Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); + // fwd->Draw( "seeds.trackId", "", "goff", 1, eventIndex ); + // fwd->Draw( "nSeedTracks", "", "goff", 1, eventIndex ); + // mTotalSeeds = fwd->GetV1()[0]; + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Seeds : %d", mTotalSeeds ) ); n(); } @@ -452,15 +508,17 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ printf( "Visualizing Event %d \n", eventIndex ); - fwd->Draw( "reco.id", "", "", 1, eventIndex ); - int nTrk = fwd->GetSelectedRows(); //number of reco tracks - printf( "Event has %d Tracks \n", nTrk ); //changed from %lld to %d to eliminate an error that occurred-AGE + fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, eventIndex ); + int nTrk = fwd->GetSelectedRows(); + printf( "Event has %lld Tracks \n", nTrk ); hFrame->Draw("colz"); - //add detector locations - if (projType == kRZSigned){ + viz_points( "FTT", "fttPoints.mXYZ.fX:fttPoints.mXYZ.fY:fttPoints.mXYZ.fZ", kRed, eventIndex, projType ); + // viz_points( "FTC", "fttClusters.pos.fX:fttClusters.pos.fY:-fttClusters.pos.fZ", kGreen, eventIndex, projType, "fttClusters.mNStrips>2" ); + viz_points( "FST", "fstHits.mXYZ.fX:fstHits.mXYZ.fY:fstHits.mXYZ.fZ", kRed, eventIndex, projType ); + viz_points( "FCS", "wcalClusters.mXYZ.fX:wcalClusters.mXYZ.Y():wcalClusters.mXYZ.Z():wcalClusters.mClu.mEnergy", kGray, eventIndex, projType ); TLine *fst1 = new TLine(151.75, -28.3, 151.75, 28.3); fst1->SetLineWidth(2); @@ -475,22 +533,9 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ fst3->SetLineColor(12); fst3->Draw("same"); - TLine *ftt1 = new TLine(281, -60, 281, 60); - ftt1->SetLineWidth(2); - ftt1->SetLineColor(12); - ftt1->Draw("same"); - TLine *ftt2 = new TLine(304, -60, 304, 60); - ftt2->SetLineWidth(2); - ftt2->SetLineColor(12); - ftt2->Draw("same"); - TLine *ftt3 = new TLine(325, -60, 325, 60); - ftt3->SetLineWidth(2); - ftt3->SetLineColor(12); - ftt3->Draw("same"); - TLine *ftt4 = new TLine(348, -60, 348, 60); - ftt4->SetLineWidth(2); - ftt4->SetLineColor(12); - ftt4->Draw("same"); + + viz_tracks(nTrk, eventIndex, projType, false); + //viz_seeds(nTrk, eventIndex, projType); TLine *epd = new TLine(375, -130, 375, 130); epd->SetLineWidth(2); @@ -510,15 +555,15 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ //viz_points( "FST", "fstX:fstY:fstZ", kGray, eventIndex, projType/*, true*/ ); //viz_points( "EPD", "epdX:epdY:epdZ:epdE", kBlue, eventIndex, projType/*, true*/ ); //epd hits (only in fwdtree2)-AGE //viz_points( "FCS", "fcsX:fcsY:fcsZ:fcsE", kGreen, eventIndex, projType/*, true*/ ); - viz_points( "FST", "fst.pos.fX:fst.pos.fY:fst.pos.fZ", kGray, eventIndex, projType, true ); - viz_points( "FTT", "ftt.pos.fX:ftt.pos.fY:ftt.pos.fZ", kRed, eventIndex, projType ); - viz_points( "FTT Clusters", "fttClusters.pos.fX:fttClusters.pos.fY:fttClusters.pos.fZ", kRed, eventIndex, projType ); - viz_points( "WCal Hits", "wcalHits.starXYZ.fX:wcalHits.starXYZ.fY:wcalHits.starXYZ.fZ+705:100*wcalHits.energy", kBlue, eventIndex, projType ); - viz_points( "HCal Hits", "hcalHits.starXYZ.fX:hcalHits.starXYZ.fY:hcalHits.starXYZ.fZ+785:100*wcalClusters.mEnergy", kTeal, eventIndex, projType/*, true*/ ); - viz_points( "WCal Clusters", "wcalClusters.pos.fX:wcalClusters.pos.fY:wcalClusters.pos.fZ+705:100*wcalClusters.mEnergy", kViolet, eventIndex, projType/*, true*/ ); - viz_points( "HCal Clusters", "hcalClusters.pos.fX:hcalClusters.pos.fY:hcalClusters.pos.fZ+785:100*wcalClusters.mEnergy", kGreen, eventIndex, projType/*, true*/ ); //add fcs hits-AGE - - viz_seed( "Seeds", "seeds.pos.fX:seeds.pos.fY:seeds.pos.fZ", eventIndex, projType ); + viz_points( "FST", "fst.mXYZ.fX:fst.mXYZ.fY:fst.mXYZ.fZ", kGray, eventIndex, projType, true ); + viz_points( "FTT", "ftt.mXYZ.fX:ftt.mXYZ.fY:ftt.mXYZ.fZ", kRed, eventIndex, projType ); + // viz_points( "FTT Clusters", "fttClusters.pos.fX:fttClusters.pos.fY:fttClusters.pos.fZ", kRed, eventIndex, projType ); + // viz_points( "WCal Hits", "wcalHits.starXYZ.fX:wcalHits.starXYZ.fY:wcalHits.starXYZ.fZ+705:100*wcalHits.energy", kBlue, eventIndex, projType ); + // viz_points( "HCal Hits", "hcalHits.starXYZ.fX:hcalHits.starXYZ.fY:hcalHits.starXYZ.fZ+785:100*wcalClusters.mEnergy", kTeal, eventIndex, projType/*, true*/ ); + // viz_points( "WCal Clusters", "wcalClusters.pos.fX:wcalClusters.pos.fY:wcalClusters.pos.fZ+705:100*wcalClusters.mEnergy", kViolet, eventIndex, projType/*, true*/ ); + // viz_points( "HCal Clusters", "hcalClusters.pos.fX:hcalClusters.pos.fY:hcalClusters.pos.fZ+785:100*wcalClusters.mEnergy", kGreen, eventIndex, projType/*, true*/ ); //add fcs hits-AGE + + // viz_seed( "Se-=[eds", "seeds.pos.fX:seeds.pos.fY:seeds.pos.fZ", eventIndex, projType ); //viz_proj( eventIndex, projType, false); //viz_points( "Proj", "reco.reco.projs.mXYZ.fX:reco.reco.projs.mXYZ.fY:reco.reco.projs.mXYZ.fZ", kRed, eventIndex, projType); return nTrk; @@ -526,9 +571,10 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ //change to name of file being used-AGE -void viz( TString fn = "fwdtree5.root", int view = kXY) { +void viz( int maxEvents = 10, TString fn = "fwdtree.root", int view = kXY) { + +void viz( int mode = 0, int maxEvents = 10, TString fn = "fwdtree.root") { - ProjectionType pjt = (ProjectionType)view; fData = new TFile( fn ); fwd = (TTree*)fData->Get( "fwd" ); @@ -561,6 +607,7 @@ void viz( TString fn = "fwdtree5.root", int view = kXY) { // gPad->SetMargin(0.1, 0.05, 0.15, 0.05); int nEvents = fwd->GetEntries(); + if (nEvents > maxEvents) nEvents = maxEvents; // nEvents = 1; for ( int iEvent = 0; iEvent < nEvents; iEvent ++ ){ @@ -581,7 +628,7 @@ void viz( TString fn = "fwdtree5.root", int view = kXY) { padStat->cd(); padStat->Clear(); - viz_stats( iEvent ); //changed to provide number of tracks as well-AGE + // viz_stats( iEvent ); //changed to provide number of tracks as well-AGE padStat->Update(); gCan->Update(); gCan->Print( TString::Format( "out_event%d.pdf", iEvent ) ); @@ -595,4 +642,37 @@ void viz( TString fn = "fwdtree5.root", int view = kXY) { hFrame->Reset(); } -} \ No newline at end of file + if ( mode != 1 ) return; + // visualize the event one track at a time + for ( int inEvent = 0; inEvent < nEvents; inEvent++ ){ + fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, inEvent ); + int nTrk = fwd->GetSelectedRows(); + printf( "Event %d has %lld Tracks \n", inEvent, nTrk ); + + for ( int iTrack = 0; iTrack < nTrk; iTrack ++ ){ + + printf( "Track: %d\n", iTrack ); + + padRZ->cd(); + // int nTrk = viz_event( iEvent, kRZSigned ); + viz_event( inEvent, kRZSigned, true ); + viz_tracks(nTrk, inEvent, kRZSigned, true, iTrack); + padXY->cd(); + viz_event( inEvent, kXY, true ); + viz_tracks(nTrk, inEvent, kXY, true, iTrack); + if (nTrk > -1){ + padRZ->Update(); + padXY->Update(); + + padStat->cd(); + padStat->Clear(); + // viz_stats( iEvent ); + padStat->Update(); + gCan->Update(); + gCan->Print( TString::Format( "out_event%d_track%d.pdf", inEvent, iTrack ) ); + } + hFrame->Reset(); + } + } + +} diff --git a/StRoot/StFwdTrackMaker/macro/viz2.C b/StRoot/StFwdTrackMaker/macro/viz2.C new file mode 100755 index 00000000000..be2db879e82 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/viz2.C @@ -0,0 +1,600 @@ +//usr/bin/env root -l -b -q $0'('$1')'; exit $? +#include "TFile.h" +#include "TH1F.h" +#include "TH2F.h" +#include "TTree.h" + + +TFile * fData; +TTree * fwd; +TH2 * hFrame; +TCanvas *gCan; +TPad *padRZ, *padXY, *padStat; + +float LegendX, LegendY; +float lineScale = 1.5; + +enum ProjectionType { kXY, kRZ, kRZSigned, kXZ, kYZ }; + +float xx( float x, float y, float z, ProjectionType proj = kRZ ){ + + if ( proj == kRZ || proj == kRZSigned){ + return z;//(TMath::ATan2( y, x ) + 2*3.1415926 )/ (2*3.14159) * 360; + } else if ( proj == kXY ){ + return x; + } else if ( proj == kXZ ){ + return z; + } else if ( proj == kYZ ){ + return z; + } + + return x; +} + +float yy( float x, float y, float z, ProjectionType proj = kRZ ){ + + if ( proj == kRZ ){ + float r = sqrt( pow(x, 2) + pow(y, 2) ); + return r; + } else if ( proj == kXY ){ + return y; + } else if ( proj == kRZSigned ){ + float r = sqrt( pow(x, 2) + pow(y, 2) ); + if ( y == 0 ) return r; + r *= y / fabs(y); + return r; + } else if ( proj == kXZ ){ + return x; + } else if ( proj == kYZ ){ + return y; + } + + return y; +} + +void viz_points(const char* name, const char* cmd, int color, int eventIndex, ProjectionType projType, bool Legend = false ){ + + fwd->Draw( cmd, "", "goff", 1, eventIndex ); + int N = fwd->GetSelectedRows(); + printf( "%s : has %d results \n", cmd, N ); + printf( "Projection Mode : %d \n", projType ); + + auto cmdX = fwd->GetV1(); + auto cmdY = fwd->GetV2(); + auto cmdZ = fwd->GetV3(); + auto cmdE = fwd->GetV4(); + if ( cmdE != nullptr ){ + printf( "TOWERS\n" ); + } + float vizX; //change from array-AGE + float vizY; + + TText *t = new TText(.5,.5,"Hello World !"); + // t->SetTextAlign(22); + t->SetTextColor(kBlack); + t->SetTextFont(43); + t->SetTextSize(20); + + int zColorStep = 90; + int slc = color; + int zColors[50]; // fst1 fst2 fst3 ftt1 ftt2 ftt3 ftt4 epd ecal hcal + float zSizes[] = {2.5, 2.5, 2.0, 1.5, 1.5, 1.5, 1.5, 1.5, 2.5, 2.0, 1.5}; //first element is for hits that don't match any positions (only goes to ftt3--changing to allow all) + for ( int i = 0; i < 50; i++ ) + zColors[i] = TColor::GetColorPalette(i*zColorStep % 255 ); + + + bool lgZ = false; + float alpha = 0.6; + for ( int i = 0; i < N; i++ ){ + + vizX = xx( cmdX[i], cmdY[i], cmdZ[i], projType ); + vizY = yy( cmdX[i], cmdY[i], cmdZ[i], projType ); + printf( "\tpoint at (%f, %f, %f) -> (%f, %f)\n", cmdX[i], cmdY[i], cmdZ[i], vizX, vizY ); + + int zIndex = 0; + if ( fabs( cmdZ[i] - 151.75) < 2.5 ) zIndex = 1; + if ( fabs( cmdZ[i] - 165.25) < 2.5 ) zIndex = 2; + if ( fabs( cmdZ[i] - 178.75) < 2.5 ) zIndex = 3; + + //add locations of other detectors-AGE + //FTT--approximate locations + if ( fabs( cmdZ[i] - 281) < 2.5 ) zIndex = 4; + if ( fabs( cmdZ[i] - 304) < 2.5 ) zIndex = 5; + if ( fabs( cmdZ[i] - 325) < 2.5 ) zIndex = 6; + if ( fabs( cmdZ[i] - 348) < 2.5 ) zIndex = 7; + //EPD--approx. + if ( fabs( cmdZ[i] - 375) < 2.5 ) zIndex = 8; + //FCS--approx. + //if ( fabs( cmdZ[i] - 721) < 2.5 ) zIndex = 9; //wcal + //if ( fabs( cmdZ[i] - 804) < 2.5 ) zIndex = 10; //hcal + + TMarker *mk = new TMarker( vizX, vizY, 20 ); + + mk->SetMarkerSize( 2.5 ); + if (zIndex >= 1 && zIndex < 50){ //see if should be changed to zIndex < 9-AGE + slc = zColors[zIndex]; + } + mk->SetMarkerSize( zSizes[zIndex] ); + + + + + // mk->SetMarkerSize( (float)(zIndex) * 0.5 + 0.5 ); + + alpha = 0.6; + if ( zIndex != 8 && (cmdE != nullptr && projType == kRZSigned) ){ //FCS for RZ + //mk->SetMarkerStyle( 21 ); //sets marker to a square, change to use TBox instead-AGE + //mk->SetMarkerSize( 0.5 + 0.5 * cmdE[i] ); + mk->SetMarkerSize(0); + alpha = (cmdE[i] / 10.0); + if (alpha>=1) alpha = 1; + TBox *box = new TBox( vizX-0.05*cmdE[i], vizY-0.5, vizX, vizY+0.5 ); + box->SetFillColor(210); + if ( name == "WCal Clusters" || name == "HCal CLusters" ){ + box->SetFillColor(880); + mk->SetMarkerSize(1); + } + box->Draw("same"); + } + if ( name == "FTT Clusters" && projType == kXY ){ + mk->SetMarkerSize(0); + TLine XCluster; + XCluster.SetLineWidth(1); + XCluster.SetLineColor(9); //dark blue + TLine YCluster; + YCluster.SetLineWidth(1); + YCluster.SetLineColor(46); //dark red + float x0; + float x1; + float y0; + float y1; + if (vizX < 0){ + x0 = -50; + x1 = 0; + } else if(vizX >= 0){ + x0 = 0; + x1 = 50; + } + if (vizY < 0){ + y0 = -50; + y1 = 0; + } else if (vizY >= 0){ + y0 = 0; + y1 = 50; + } + + XCluster.DrawLine(vizX, y0, vizX, y1); + YCluster.DrawLine(x0, vizY, x1, vizY); + + } + + if ( cmdE != nullptr && (zIndex == 8 || projType != kRZSigned) ){ //EPD for RZ and EPD and FCS for XY + mk->SetMarkerStyle(21); + mk->SetMarkerSize( 0.005 * cmdE[i]); + } + + printf( "\tzIndex = %d -> color = %d \n", zIndex, slc ); + + mk->SetMarkerColorAlpha( slc, alpha ); + if ( zIndex >= 1 ){ + mk->SetMarkerColorAlpha( slc, alpha ); + lgZ = true; + } + + //change marker style etc. for projected points only-AGE + /*if( name == "Proj" ){ + mk->SetMarkerStyle(23); + mk->SetMarkerColor(2); + mk->SetMarkerSize(1.5); + }*/ + + mk->Draw("same"); + + } + + if ( lgZ ){ + /*for ( int i = 1; i < 4; i++){ + TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColorAlpha( zColors[i], 0.5 ); + mk1->Draw("same"); + t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s: %d", name, i ) ); + + LegendY -= 5; + }*/ + if (name == "FST"){ + for ( int i = 1; i < 4; i++ ){ + TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColorAlpha( zColors[i], 0.5 ); + mk1->Draw("same"); + t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s: %d", name, i ) ); + + LegendY -= 5; + } + } else if (name == "FTT"){ + for ( int i = 1; i < 5; i++ ){ + TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColorAlpha( zColors[i+3], 0.5 ); + mk1->Draw("same"); + t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s: %d", name, i ) ); + + LegendY -= 5; + } + } else if (name == "FCS"){ + for ( int i = 1; i < 3; i++ ){ + TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColorAlpha( zColors[i], 0.5 ); + mk1->Draw("same"); + t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s: %d", name, i ) ); + + LegendY -= 5; + } + } + + } else { + TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColor( color ); + mk1->Draw("same"); + t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s:", name ) ); + + LegendY -= 5; + } +} + +//add function for seed finding-AGE +void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType projType = kRZSigned){ + + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); + int nTrks = fwd->GetSelectedRows(); + + TLine line; + line.SetLineWidth(2); + line.SetLineColor(1); + TLine proj; + for (int i = 0; i < nTrks; i++){ //loop over number of tracks + + fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); + auto nHits = fwd->GetSelectedRows(); + auto projX = fwd->GetV1(); + auto projY = fwd->GetV2(); + auto projZ = fwd->GetV3(); + /*std::vector projX; + std::vector projY; + std::vector projZ; + + for (int hit = 0; hit < nHits; ++hit) { + projX.push_back(fwd->GetV1()[hit]); + projY.push_back(fwd->GetV2()[hit]); + projZ.push_back(fwd->GetV3()[hit]); + }*/ + + //select only the seeds that have same track id as track number + fwd->Draw( cmd, TString::Format("seeds.mTrackId == %d", i), "goff", 1, eventIndex ); + //fwd->Draw( TString::Format("seeds[%d].mXYZ.fX:seeds[%d].mXYZ.fY:seeds[%d].mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); + int numSeeds = fwd->GetSelectedRows(); + auto newX = fwd->GetV1(); + auto newY = fwd->GetV2(); + auto newZ = fwd->GetV3(); + + for ( int j = 0; j < numSeeds - 1; j++){ + + float x0 = xx( newX[j], newY[j], newZ[j], projType ); + float y0 = yy( newX[j], newY[j], newZ[j], projType ); + float x1 = xx( newX[j+1], newY[j+1], newZ[j+1], projType ); + float y1 = yy( newX[j+1], newY[j+1], newZ[j+1], projType ); + + /*if ( fabs(x0 - projX[j+1]) <= 1 ){ + line.SetLineColor(1); + }*/ + + line.DrawLine(x0, y0, x1, y1); + } + + } +} + +//add function for track projection +void viz_proj( int eventIndex, ProjectionType projType = kRZSigned, bool markers = false ){ + + //get number of tracks + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex); //check if this is correct data to use to get nTrks + int nTrks = fwd->GetSelectedRows(); + + //create line for track + TLine trkproj; + trkproj.SetLineWidth(1.5); + trkproj.SetLineColor(24); //light green + + //loop over each track in the event + for ( int i = 0; i < nTrks; i++ ){ + + //get hits in i'th track + fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); + auto nHits = fwd->GetSelectedRows(); + auto projX = fwd->GetV1(); + auto projY = fwd->GetV2(); + auto projZ = fwd->GetV3(); + + + //loop over hits in each track + for ( int j = 0; j < nHits - 1; j++ ){ + + //assign the x and y positions of the track projection + float x0 = xx( projX[j], projY[j], projZ[j], projType ); + float y0 = yy( projX[j], projY[j], projZ[j], projType ); + float x1 = xx( projX[j+1], projY[j+1], projZ[j+1], projType ); + float y1 = yy( projX[j+1], projY[j+1], projZ[j+1], projType ); + + /*trkproj.SetLineColor(i+2); + if (i == 0 || i == 10 ){ + trkproj.SetLineColor(1); + }*/ + trkproj.DrawLine(x0, y0, x1, y1); + } + + //add markers + if (markers){ + for ( int j = 0; j < nHits; j++ ){ + + float x = xx( projX[j], projY[j], projZ[j], projType ); + float y = yy( projX[j], projY[j], projZ[j], projType ); + + TMarker *mk = new TMarker( x, y, 20); + mk->SetMarkerStyle(23); + mk->SetMarkerColor(2); + mk->SetMarkerSize(1.5); + + mk->Draw("same"); + } + } + } + if (markers){ + //add marker to the legend + TText *t = new TText(.5,.5,"Hello World !"); + t->SetTextColor(kBlack); + t->SetTextFont(43); + t->SetTextSize(20); + //make this more functional? + if ( projType == kRZSigned ){ + LegendY = 5; + } else if (projType == kXY ){ + LegendY = -15; + } + TMarker *mk1 = new TMarker( LegendX, LegendY, 23 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColor( 2 ); + mk1->Draw("same"); + t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "Projected Hits ") ); + } + +} //end of fn + + +//add function to compare lines +//float comp_lines() + + +float statTextY = 0.97; +void n() { statTextY -= 0.05; } +void viz_stats( int eventIndex ){ + statTextY = 0.97; + TText text; + text.SetTextFont(43); + text.SetTextSize(36); + + + /*fwd->Draw( "fstX:fstY:fstZ", "", "goff", 1, eventIndex ); + int numEpd = fwd->GetSelectedRows(); + fwd->Draw( "fttX:fttY:fttZ", "", "goff", 1, eventIndex ); + int numEpd = fwd->GetSelectedRows(); + fwd->Draw( "epdX:epdY:epdZ", "", "goff", 1, eventIndex ); + int numEpd = fwd->GetSelectedRows(); + fwd->Draw( "fcsX:fcsY:fcsZ", "", "goff", 1, eventIndex ); + int numEpd = fwd->GetSelectedRows();*/ + + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); + int numTracks = fwd->GetSelectedRows(); + fwd->Draw( "fstHits.mXYZ.fX:fstHits.mXYZ.fY:fstHits.mXYZ.fZ", "", "goff", 1, eventIndex ); + int numFst = fwd->GetSelectedRows(); + fwd->Draw( "fttPoints.mXYZ.fX:fttPoints.mXYZ.fY:fttPoints.mXYZ.fZ", "", "goff", 1, eventIndex ); + int numFtt = fwd->GetSelectedRows(); + //fwd->Draw( "EPD hits", "", "goff", 1, eventIndex ); + //int numEpd = fwd->GetSelectedRows(); + fwd->Draw( "wcalHits.mXYZ.fX:wcalHits.mXYZ.fY:wcalHits.mXYZ.fZ", "", "goff", 1, eventIndex ); + int numWcalHits = fwd->GetSelectedRows(); + fwd->Draw( "hcalHits.mXYZ.fX:hcalHits.mXYZ.fY:hcalHits.mXYZ.fZ", "", "goff", 1, eventIndex ); + int numHcalHits = fwd->GetSelectedRows(); + fwd->Draw( "wcalClusters.mXYZ.fX:wcalClusters.mXYZ.fY:wcalClusters.mXYZ.fZ", "", "goff", 1, eventIndex ); + int numWcal = fwd->GetSelectedRows(); + fwd->Draw( "hcalClusters.mXYZ.fX:hcalClusters.mXYZ.fY:hcalClusters.mXYZ.fZ", "", "goff", 1, eventIndex ); + int numHcal = fwd->GetSelectedRows(); + + text.DrawTextNDC( 0.05, statTextY, TString::Format("Event : %d", eventIndex) ); n(); + text.DrawTextNDC( 0.05, statTextY, TString::Format("Tracks : %d", numTracks) ); n(); + text.DrawTextNDC( 0.05, statTextY, TString::Format("FST Hits : %d", numFst) ); n(); + text.DrawTextNDC( 0.05, statTextY, TString::Format("FTT Hits : %d", numFtt) ); n(); + //text.DrawTextNDC( 0.05, statTextY, TString::Format("EPD Hits : %d", numEpd) ); n(); + //text.DrawTextNDC( 0.05, statTextY, TString::Format("WCal Hits : %d", numWcalHits) ); n(); + //text.DrawTextNDC( 0.05, statTextY, TString::Format("HCal Hits : %d", numHcalHits) ); n(); + text.DrawTextNDC( 0.05, statTextY, TString::Format("WCal Clusters : %d", numWcal) ); n(); + text.DrawTextNDC( 0.05, statTextY, TString::Format("HCal Clusters : %d", numHcal) ); n(); + + //print reco statistics + /*fwd->Draw( "reco.mProjections.mXYZ:fX:reco.mProjections.mXYZ:fY:reco.mProjections.mXYZ:fZ", "", "goff", 1, eventIndex ); + int numReco = fwd->GetSelectedRows(); + statTextY = 0.92; + text.DrawTextNDC( 0.35, statTextY, TString::Format("Reco Hits : %d", numReco) ); n();*/ + +} + + +int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ + + if ( projType == kRZSigned || projType == kXZ || projType == kYZ ){ + hFrame = new TH2F( "hFrame", ";z;R", 520, -30, 900, 260, -130, 130 ); + hFrame->SetTitle( "Event Visualization (RZ Signed)" ); + LegendX = 10; + LegendY = 60; + } else if ( projType == kRZ ){ + hFrame = new TH2F( "hFrame", ";z;R", 500, 0, 900, 60, 0, 60 ); + hFrame->SetTitle( "Event Visualization (RZ Signed)" ); + LegendX = 10; + LegendY = 60; + } else if ( projType == kXY ){ + hFrame = new TH2F( "hFrame", ";x;y", 5, -50, 50, 5, -50, 50 ); + hFrame->SetTitle( "Event Visualization (XY)" ); + LegendX = -40; + LegendY = 40; + } + + printf( "Visualizing Event %d \n", eventIndex ); + + fwd->Draw( "reco.mChi2", "", "", 1, eventIndex ); + int nTrk = fwd->GetSelectedRows(); //number of reco tracks + printf( "Event has %d Tracks \n", nTrk ); //changed from %lld to %d to eliminate an error that occurred-AGE + + + hFrame->Draw("colz"); + + //add detector locations + if (projType == kRZSigned){ + + TLine *fst1 = new TLine(151.75, -28.3, 151.75, 28.3); + fst1->SetLineWidth(2); + fst1->SetLineColor(12); + fst1->Draw("same"); + TLine *fst2 = new TLine(165.25, -28.3, 165.25, 28.3); + fst2->SetLineWidth(2); + fst2->SetLineColor(12); + fst2->Draw("same"); + TLine *fst3 = new TLine(178.75, -28.3, 178.75, 28.3); + fst3->SetLineWidth(2); + fst3->SetLineColor(12); + fst3->Draw("same"); + + TLine *ftt1 = new TLine(281, -60, 281, 60); + ftt1->SetLineWidth(2); + ftt1->SetLineColor(12); + ftt1->Draw("same"); + TLine *ftt2 = new TLine(304, -60, 304, 60); + ftt2->SetLineWidth(2); + ftt2->SetLineColor(12); + ftt2->Draw("same"); + TLine *ftt3 = new TLine(325, -60, 325, 60); + ftt3->SetLineWidth(2); + ftt3->SetLineColor(12); + ftt3->Draw("same"); + TLine *ftt4 = new TLine(348, -60, 348, 60); + ftt4->SetLineWidth(2); + ftt4->SetLineColor(12); + ftt4->Draw("same"); + + TLine *epd = new TLine(375, -130, 375, 130); + epd->SetLineWidth(2); + epd->SetLineColor(12); + epd->Draw("same"); + + //add tboxes for fcs + TBox *wcal = new TBox( 720, -120, 735, 120 ); + wcal->SetFillColorAlpha(4, 0.2); + wcal->Draw("same"); + TBox *hcal = new TBox( 800, -120, 815, 120 ); + hcal->SetFillColorAlpha(2, 0.2); + hcal->Draw("same"); + + } + + //viz_points( "FST", "fstX:fstY:fstZ", kGray, eventIndex, projType/*, true*/ ); + //viz_points( "EPD", "epdX:epdY:epdZ:epdE", kBlue, eventIndex, projType/*, true*/ ); //epd hits (only in fwdtree2)-AGE + //viz_points( "FCS", "fcsX:fcsY:fcsZ:fcsE", kGreen, eventIndex, projType/*, true*/ ); + viz_points( "FST", "fstHits.mXYZ.fX:fstHits.mXYZ.fY:fstHits.mXYZ.fZ", kGray, eventIndex, projType, true ); + viz_points( "FTT", "fttPoints.mXYZ.fX:fttPoints.mXYZ.fY:fttPoints.mXYZ.fZ", kRed, eventIndex, projType ); + // viz_points( "FTT Clusters", "fttClusters.mXYZ.fX:fttClusters.mXYZ.fY:fttClusters.mXYZ.fZ", kRed, eventIndex, projType ); + viz_points( "WCal Hits", "wcalHits.mXYZ.fX:wcalHits.mXYZ.fY:wcalHits.mXYZ.fZ+705:100*wcalHits.mHit.mEnergy", kBlue, eventIndex, projType ); + viz_points( "HCal Hits", "hcalHits.mXYZ.fX:hcalHits.mXYZ.fY:hcalHits.mXYZ.fZ+785:100*wcalClusters.mClu.mEnergy", kTeal, eventIndex, projType/*, true*/ ); + viz_points( "WCal Clusters", "wcalClusters.mXYZ.fX:wcalClusters.mXYZ.fY:wcalClusters.mXYZ.fZ:100*wcalClusters.mClu.mEnergy", kViolet, eventIndex, projType/*, true*/ ); + viz_points( "HCal Clusters", "hcalClusters.mXYZ.fX:hcalClusters.mXYZ.fY:hcalClusters.mXYZ.fZ:100*wcalClusters.mClu.mEnergy", kGreen, eventIndex, projType/*, true*/ ); //add fcs hits-AGE + + viz_seed( "Seeds", "seeds.mXYZ.fX:seeds.mXYZ.fY:seeds.mXYZ.fZ", eventIndex, projType ); + viz_proj( eventIndex, projType, false); + viz_points( "Proj", "reco.mProjections.mXYZ.fX:reco.mProjections.mXYZ.fY:reco.mProjections.mXYZ.fZ", kRed, eventIndex, projType); + return nTrk; +} + + +//change to name of file being used-AGE +void viz2( TString fn = "fwdtree.root", int view = kXY) { + + ProjectionType pjt = (ProjectionType)view; + fData = new TFile( fn ); + fwd = (TTree*)fData->Get( "fwd" ); + + gStyle->SetOptStat(0); + + float canWidth = 19 * 100; + float canHeight = 16 * 100; + gCan = new TCanvas( "g", "", canWidth, canHeight ); + gCan->SetMargin( 0, 0, 0, 0); + gCan->cd(); + gCan->Draw(); + + padRZ = new TPad( "padRZ", "", 0.0, 0.5, 0.95, 0.99 ); + padRZ->SetMargin( .05,.01,.05,.01 ); + padRZ->Draw("same"); + padRZ->cd(); + + gCan->cd(); + padXY = new TPad( "padXY", "", 0.0, 0.0, 0.5, 0.5 ); + padXY->SetMargin( .1,.02,.05,.01 ); + padXY->Draw("same"); + padXY->cd(); + + gCan->cd(); + padStat = new TPad( "padStat", "", 0.5, 0.0, 1.0, 0.5 ); + padStat->SetMargin( .1,.02,.05,.01 ); + padStat->Draw("same"); + padStat->cd(); + + // gPad->SetMargin(0.1, 0.05, 0.15, 0.05); + + int nEvents = fwd->GetEntries(); + // nEvents = 1; + // nEvents = 10; + for ( int iEvent = 0; iEvent < nEvents; iEvent ++ ){ + + printf( "Event: %d\n", iEvent ); + padRZ->cd(); + + //TBox *wcal = new TBox( 720, -60, 735, 60 ); + //wcal->SetFillColor(4); + //wcal->Draw(""); + int nTrk = viz_event( iEvent, kRZSigned ); + + + padXY->cd(); + viz_event( iEvent, kXY ); + if (nTrk > -1){ + padRZ->Update(); + padXY->Update(); + + padStat->cd(); + padStat->Clear(); + viz_stats( iEvent ); //changed to provide number of tracks as well-AGE + padStat->Update(); + gCan->Update(); + gCan->Print( TString::Format( "out_event%d.pdf", iEvent ) ); + } + + + // cin.get(); + // if (viz_event( iEvent ) > 0 ) + // break; + + hFrame->Reset(); + } + +} diff --git a/StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx b/StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx index 031a156db9e..0f66f8c0c68 100644 --- a/StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx +++ b/StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx @@ -850,17 +850,17 @@ void StMuDstMaker::setBranchAddresses(TChain* chain) { mStMuDst->set(this); } - if (!mFmsCollection) { - mFmsCollection=new StMuFmsCollection(); - connectFmsCollection(); - mStMuDst->set(this); - } - - if (!mRHICfCollection) { - mRHICfCollection=new StMuRHICfCollection(); - connectRHICfCollection(); - mStMuDst->set(this); - } + // if (!mFmsCollection) { + // mFmsCollection=new StMuFmsCollection(); + // connectFmsCollection(); + // mStMuDst->set(this); + // } + + // if (!mRHICfCollection) { + // mRHICfCollection=new StMuRHICfCollection(); + // connectRHICfCollection(); + // mStMuDst->set(this); + // } if (!mFcsCollection) { mFcsCollection=new StMuFcsCollection(); @@ -1049,7 +1049,7 @@ void StMuDstMaker::fillTrees(StEvent* ev, StMuCut* cut){ fillDetectorStates(ev); fillEmc(ev); fillPmd(ev); - fillFms(ev); + // fillFms(ev); fillRHICf(ev); fillFcs(ev); fillFtt(ev); diff --git a/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx b/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx index 716b272e824..2d97a49bfb0 100644 --- a/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx +++ b/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx @@ -3,7 +3,14 @@ #include "StEvent/StFwdTrack.h" -StMuFwdTrack::StMuFwdTrack() { +void StMuFwdTrackSeedPoint::set( StFwdTrackSeedPoint* sp ){ + mXYZ.SetXYZ( sp->mXYZ.x(), sp->mXYZ.y(), sp->mXYZ.z() ); + mSector = sp->mSector; + mTrackId = sp->mTrackId; + memcpy( mCov, sp->mCov, sizeof( mCov ) ); + } + +StMuFwdTrack::StMuFwdTrack() : mDidFitConverge(0),mDidFitConvergeFully(0),mNumberOfFailedPoints(0),mNumberOfSeedPoints(0),mNumberOfFitPoints(0),mChi2(0),mNDF(0),mPval(0),mCharge(0),mPrimaryMomentum(0,0,0),mIdTruth(0),mQATruth(0) { } @@ -19,6 +26,15 @@ void StMuFwdTrack::set( StFwdTrack * evTrack) { mCharge = evTrack->charge(); mPrimaryMomentum = TVector3( evTrack->momentum().x(), evTrack->momentum().y(), evTrack->momentum().z() ); + mIdTruth = evTrack->idTruth(); + mQATruth = evTrack->qaTruth(); + + auto dca = evTrack->dca(); + setDCA( TVector3( dca.x(), dca.y(), dca.z() ) ); + + // copy the vertex index over + mVtxIndex = evTrack->vertexIndex(); + //copy the projections for ( auto proj : evTrack->mProjections ){ mProjections.push_back( @@ -28,16 +44,12 @@ void StMuFwdTrack::set( StFwdTrack * evTrack) { //copy the FTT Seed Points for ( auto sp : evTrack->mFTTPoints ){ - mFTTPoints.push_back( - StMuFwdTrackSeedPoint( TVector3( sp.mXYZ.x(), sp.mXYZ.y(), sp.mXYZ.z() ), sp.mSector, sp.mTrackId, sp.mCov ) - ); + mFTTPoints.push_back(StMuFwdTrackSeedPoint(&sp)); } //copy the FST Seed Points for ( auto sp : evTrack->mFSTPoints ){ - mFSTPoints.push_back( - StMuFwdTrackSeedPoint( TVector3( sp.mXYZ.x(), sp.mXYZ.y(), sp.mXYZ.z() ), sp.mSector, sp.mTrackId, sp.mCov ) - ); + mFSTPoints.push_back(StMuFwdTrackSeedPoint(&sp)); } } diff --git a/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h b/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h index 11dad825e43..74b1461b2d3 100644 --- a/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h +++ b/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h @@ -16,10 +16,7 @@ #include "StMuFcsCluster.h" - class StFwdTrack; - - struct StMuFwdTrackProjection : public TObject { StMuFwdTrackProjection() {} StMuFwdTrackProjection ( const StMuFwdTrackProjection & other) { @@ -68,17 +65,39 @@ struct StMuFwdTrackProjection : public TObject { ClassDef(StMuFwdTrackProjection, 1) }; +class StFwdTrackSeedPoint; struct StMuFwdTrackSeedPoint : public TObject{ StMuFwdTrackSeedPoint() {} StMuFwdTrackSeedPoint( TVector3 xyz, short sec, unsigned short trackId, float cov[9] ){ + set( xyz, sec, trackId, cov ); + } + StMuFwdTrackSeedPoint( StFwdTrackSeedPoint *sp ){ + set( sp ); + } + + // setter + void set( TVector3 xyz, + short sec, + unsigned short trackId, + float cov[9] ){ mXYZ = xyz; mSector = sec; mTrackId = trackId; memcpy( mCov, cov, sizeof( mCov )); } + // setter from StFwdTrackSeedPoint + void set( StFwdTrackSeedPoint *sp ); + + // copy ctor + StMuFwdTrackSeedPoint( const StMuFwdTrackSeedPoint & other ){ + mXYZ = other.mXYZ; + mSector = other.mSector; + mTrackId = other.mTrackId; + memcpy( mCov, other.mCov, sizeof( mCov ) ); + } TVector3 mXYZ; unsigned short mTrackId; @@ -121,6 +140,9 @@ class StMuFwdTrack : public TObject { // Number of points used in the track seed step short numberOfSeedPoints() const; + UShort_t idTruth() const { return mIdTruth; } + UShort_t qaTruth() const { return mQATruth; } + TVector3 dca() const { return TVector3( mDCAXY, mDCAXY, mDCAZ ); } void setPrimaryMomentum( TVector3 mom ) { mPrimaryMomentum = mom; } @@ -133,46 +155,41 @@ class StMuFwdTrack : public TObject { void setNDF( float lNDF ) { mNDF = lNDF;} void setPval( float lPval ) { mPval = lPval;} void setCharge( short lCharge ) { mCharge = lCharge;} - - // ECAL clusters - // StPtrVecFcsCluster& ecalClusters(); - // const StPtrVecFcsCluster& ecalClusters() const; - // void addEcalCluster(StFcsCluster* p); - // void sortEcalClusterByET(); - // // HCAL clusters - // StPtrVecFcsCluster& hcalClusters(); - // const StPtrVecFcsCluster& hcalClusters() const; - // void addHcalCluster(StFcsCluster* p); - // void sortHcalClusterByET(); - - // vector + void setMc( UShort_t idt, UShort_t qual ) { mIdTruth = idt; mQATruth = qual; } + void setDCA( float dca[3] ) { mDCAXY = sqrt(dca[0]*dca[0]+dca[1]*dca[1]); mDCAZ = dca[2]; } + void setDCA( TVector3 dca ) { mDCAXY = sqrt(dca.X()*dca.X() + dca.Y()*dca.Y()); mDCAZ = dca.Z(); } void addEcalCluster( StMuFcsCluster* clu); void addHcalCluster( StMuFcsCluster* clu); + // FCS Cluster matches TRefArray mEcalClusters; TRefArray mHcalClusters; protected: // Track quality and convergence - bool mDidFitConverge; - bool mDidFitConvergeFully; - short mNumberOfFailedPoints; - short mNumberOfSeedPoints; - short mNumberOfFitPoints; - float mChi2; - float mNDF; - float mPval; - short mCharge; - TVector3 mPrimaryMomentum; + bool mDidFitConverge; // == 0 if the fit did not converge + bool mDidFitConvergeFully; // == 0 if the fit did not converge fully + short mNumberOfFailedPoints; // Number of points that failed to be fitted + short mNumberOfSeedPoints; // Number of points used in the track seed step + short mNumberOfFitPoints; // Number of fit points used by GenFit + float mChi2; // Chi^2 of the fit + float mNDF; // Number of degrees of freedom of the fit + float mPval; // P-value of the fit + short mCharge; // Charge of the track + TVector3 mPrimaryMomentum; // Momentum of the track at the primary vertex + /// MC track id + UShort_t mIdTruth; + /// MC track quality (percentage of hits coming from corresponding MC track) + UShort_t mQATruth; - // StPtrVecFcsCluster mEcalClusters; - // StPtrVecFcsCluster mHcalClusters; - - ClassDef(StMuFwdTrack,2) + float mDCAXY; // DCA XY to the primary vertex + float mDCAZ; // DCA Z to the primary vertex + UChar_t mVtxIndex; // Index of the vertex in the event + ClassDef(StMuFwdTrack,3) }; #endif diff --git a/StRoot/StPicoDstMaker/StPicoDstMaker.cxx b/StRoot/StPicoDstMaker/StPicoDstMaker.cxx index 4e114feba2a..fbd57892610 100644 --- a/StRoot/StPicoDstMaker/StPicoDstMaker.cxx +++ b/StRoot/StPicoDstMaker/StPicoDstMaker.cxx @@ -40,6 +40,8 @@ #include "StEvent/StTriggerData.h" #include "StEvent/StEnumerations.h" #include "StEvent/StL0Trigger.h" +#include "StEvent/StFwdTrackCollection.h" +#include "StEvent/StFwdTrack.h" #include "StMuDSTMaker/COMMON/StMuDst.h" #include "StMuDSTMaker/COMMON/StMuEvent.h" @@ -59,6 +61,9 @@ #include "StMuDSTMaker/COMMON/StMuETofHeader.h" #include "StMuDSTMaker/COMMON/StMuMcTrack.h" #include "StMuDSTMaker/COMMON/StMuMcVertex.h" +#include "StMuDSTMaker/COMMON/StMuFcsCollection.h" +#include "StMuDSTMaker/COMMON/StMuFcsHit.h" +#include "StMuDSTMaker/COMMON/StMuFcsCluster.h" #include "StTriggerUtilities/StTriggerSimuMaker.h" #include "StTriggerUtilities/Bemc/StBemcTriggerSimu.h" @@ -70,6 +75,7 @@ #include "StEmcRawMaker/StBemcTables.h" #include "StFmsDbMaker/StFmsDbMaker.h" +#include "StFcsDbMaker/StFcsDb.h" #include "tables/St_mtdModuleToQTmap_Table.h" #include "tables/St_mtdQTSlewingCorr_Table.h" @@ -94,6 +100,9 @@ #include "StPicoEvent/StPicoBEmcSmdPHit.h" #include "StPicoEvent/StPicoETofHit.h" #include "StPicoEvent/StPicoETofPidTraits.h" +#include "StPicoEvent/StPicoFwdTrack.h" +#include "StPicoEvent/StPicoFcsHit.h" +#include "StPicoEvent/StPicoFcsCluster.h" #include "StPicoEvent/StPicoMcVertex.h" #include "StPicoEvent/StPicoMcTrack.h" #include "StPicoEvent/StPicoArrays.h" @@ -245,6 +254,9 @@ void StPicoDstMaker::streamerOff() { StPicoTrackCovMatrix::Class()->IgnoreTObjectStreamer(); StPicoETofHit::Class()->IgnoreTObjectStreamer(); StPicoETofPidTraits::Class()->IgnoreTObjectStreamer(); + StPicoFwdTrack::Class()->IgnoreTObjectStreamer(); + StPicoFcsHit::Class()->IgnoreTObjectStreamer(); + StPicoFcsCluster::Class()->IgnoreTObjectStreamer(); StPicoMcVertex::Class()->IgnoreTObjectStreamer(); StPicoMcTrack::Class()->IgnoreTObjectStreamer(); } @@ -893,6 +905,9 @@ Int_t StPicoDstMaker::MakeWrite() { fillEpdHits(); fillBbcHits(); fillETofHits(); + fillFwdTracks(); + fillFcsHits(); + fillFcsClusters(); // Could be a good idea to move this call to Init() or InitRun() StFmsDbMaker* fmsDbMaker = static_cast(GetMaker("fmsDb")); @@ -2502,6 +2517,103 @@ void StPicoDstMaker::fillMtdHits() { } //while (triggerPos.size() > 0) } +//_________________ +void StPicoDstMaker::fillFwdTracks() { + + StEvent *evt = (StEvent *)GetDataSet("StEvent"); + if ( evt ){ + StFwdTrackCollection * evc = evt->fwdTrackCollection(); + if ( !evc ){ + LOG_ERROR << "null FwdTrackCollection" << endm; + return; + } + const StSPtrVecFwdTrack& evTracks = evc->tracks(); + LOG_INFO << "Adding " << evc->numberOfTracks() << " StFwdTracks from StEvent to PicoDst" << endm; + for ( size_t i = 0; i < evc->numberOfTracks(); i++ ){ + StFwdTrack * evTrack = evTracks[i]; + StPicoFwdTrack picoFwdTrack; + // Set the PicoDst attributes + picoFwdTrack.setMomentum( evTrack->momentum().x(), evTrack->momentum().y(), evTrack->momentum().z() ); + picoFwdTrack.setNumberOfFitPoints( evTrack->numberOfFitPoints() * evTrack->charge() ); + picoFwdTrack.setNumberOfSeedPoints( evTrack->numberOfSeedPoints() ); + picoFwdTrack.setChi2( evTrack->chi2() ); + // Add the PicoDst object to the PicoArray + int counter = mPicoArrays[StPicoArrays::FwdTrack]->GetEntries(); + picoFwdTrack.setId( counter ); + new((*(mPicoArrays[StPicoArrays::FwdTrack]))[counter]) StPicoFwdTrack(picoFwdTrack); + } + } else { + LOG_WARN << "Cannot get Fwd Tracks from StEvent" << endm; + } +} //fillFwdTracks + +//_________________ +void StPicoDstMaker::fillFcsClusters() { + StFcsDb* fcsDb = static_cast(GetDataSet("fcsDb")); + if( !fcsDb ) { + LOG_ERROR << "Cannot get StFcsDb object" << endm; + return; + } + StMuFcsCollection * muFcs = mMuDst->muFcsCollection(); + if ( !muFcs ) { + LOG_ERROR << "Cannot get Fcs Collection from MuDst" << endm; + return; + } + TIter next(muFcs->getClusterArray()); + StMuFcsCluster* muCluster(NULL); + while ((muCluster = static_cast(next()))) { + int counter = mPicoArrays[StPicoArrays::FcsCluster]->GetEntries(); + StPicoFcsCluster picoFcsCluster; + picoFcsCluster.setId(counter); + picoFcsCluster.setDetectorId(muCluster->detectorId()); + picoFcsCluster.setCategory(muCluster->category()); + picoFcsCluster.setNTowers(muCluster->nTowers()); + picoFcsCluster.setEnergy(muCluster->energy()); + picoFcsCluster.setX(muCluster->x()); + picoFcsCluster.setY(muCluster->y()); + picoFcsCluster.setSigmaMin(muCluster->sigmaMin()); + picoFcsCluster.setSigmaMax(muCluster->sigmaMax()); + picoFcsCluster.setTheta(muCluster->theta()); + picoFcsCluster.setChi2Ndf1Photon(muCluster->chi2Ndf1Photon()); + picoFcsCluster.setChi2Ndf2Photon(muCluster->chi2Ndf2Photon()); + double zVertex=picoDst()->event()->primaryVertex().z(); + StThreeVectorD xyz=fcsDb->getStarXYZ(muCluster->detectorId(), muCluster->x(), muCluster->y()); + StLorentzVectorD lv = fcsDb->getLorentzVector(xyz, muCluster->energy(), zVertex); + picoFcsCluster.setFourMomentum(lv.px(),lv.py(),lv.pz(),lv.e()); + new((*(mPicoArrays[StPicoArrays::FcsCluster]))[counter]) StPicoFcsCluster(picoFcsCluster); + } + LOG_INFO << "StPicoDstMaker::fillFcsClusters filled " << mPicoArrays[StPicoArrays::FcsCluster]->GetEntries() << endm; +}//fillFcsClusters + +//_________________ +void StPicoDstMaker::fillFcsHits() { + StFcsDb* fcsDb = static_cast(GetDataSet("fcsDb")); + if( !fcsDb ) { + LOG_ERROR << "Cannot get StFcsDb object" << endm; + return; + } + StMuFcsCollection * muFcs = mMuDst->muFcsCollection(); + if ( !muFcs ) { + LOG_ERROR << "Cannot get Fcs Collection from MuDst" << endm; + return; + } + TIter next(muFcs->getHitArray()); + StMuFcsHit* muHit(NULL); + while ((muHit = static_cast(next()))) { + int counter = mPicoArrays[StPicoArrays::FcsHit]->GetEntries(); + StPicoFcsHit picoFcsHit; + picoFcsHit.setIndex(counter); + picoFcsHit.setDetectorId(muHit->detectorId()); + picoFcsHit.setId(muHit->id()); + double zVertex=picoDst()->event()->primaryVertex().z(); + StThreeVectorD xyz = fcsDb->getStarXYZ(muHit->detectorId(), muHit->id()); + StLorentzVectorD lv = fcsDb->getLorentzVector(xyz, muHit->energy(), zVertex); + picoFcsHit.setFourMomentum(lv.px(),lv.py(),lv.pz(),lv.e()); + new((*(mPicoArrays[StPicoArrays::FcsHit]))[counter]) StPicoFcsHit(picoFcsHit); + } + LOG_INFO << "StPicoDstMaker::fillFcsHits filled " << mPicoArrays[StPicoArrays::FcsHit]->GetEntries() << endm; +}//fillFcsHit + #if !defined (__TFG__VERSION__) /** diff --git a/StRoot/StPicoDstMaker/StPicoDstMaker.h b/StRoot/StPicoDstMaker/StPicoDstMaker.h index e5f91085fb2..0566fc85cd5 100644 --- a/StRoot/StPicoDstMaker/StPicoDstMaker.h +++ b/StRoot/StPicoDstMaker/StPicoDstMaker.h @@ -225,6 +225,12 @@ class StPicoDstMaker : public StMaker { void fillBbcHits(); /// Fill ETOF information void fillETofHits(); + /// Fill Fwd Track information + void fillFwdTracks(); + /// Fill FcsHits information + void fillFcsHits(); + /// Fill FcsClusters information + void fillFcsClusters(); /// Fill MC vertex information void fillMcVertices(); /// Fill MC track information diff --git a/StRoot/StPicoEvent/StPicoArrays.cxx b/StRoot/StPicoEvent/StPicoArrays.cxx index 2038c048778..3e493522ce0 100644 --- a/StRoot/StPicoEvent/StPicoArrays.cxx +++ b/StRoot/StPicoEvent/StPicoArrays.cxx @@ -25,8 +25,11 @@ const char* StPicoArrays::picoArrayNames [NAllPicoArrays] = { "Event", "BEmcSmdPHit", "ETofHit", "ETofPidTraits", - "McVertex", - "McTrack" + "McVertex", + "McTrack", + "FwdTracks", + "FcsHits", + "FcsClusters" }; // ARRAY TYPES @@ -49,8 +52,11 @@ const char* StPicoArrays::picoArrayTypes [NAllPicoArrays] = { "StPicoEvent", "StPicoBEmcSmdPHit", "StPicoETofHit", "StPicoETofPidTraits", - "StPicoMcVertex", - "StPicoMcTrack" + "StPicoMcVertex", + "StPicoMcTrack", + "StPicoFwdTrack", + "StPicoFcsHit", + "StPicoFcsCluster" }; // ARRAY SIZES @@ -76,8 +82,11 @@ int StPicoArrays::picoArraySizes [NAllPicoArrays] = { 1, // StPicoEvent 100, // StPicoBEmcSmdPHit 100, // StPicoETofHit 100, // StPicoETofPidTraits - 10, // StPicoMcVertex - 1000 // StPicoMcTrack + 10, // StPicoMcVertex + 1000, // StPicoMcTrack + 10, // StPicoFwdTrack + 200, // StPicoFcsHit + 100 // StPicoFcsCluster }; //_________________ diff --git a/StRoot/StPicoEvent/StPicoArrays.h b/StRoot/StPicoEvent/StPicoArrays.h index aad476f02d0..a107091cdcd 100644 --- a/StRoot/StPicoEvent/StPicoArrays.h +++ b/StRoot/StPicoEvent/StPicoArrays.h @@ -17,7 +17,7 @@ class StPicoArrays { StPicoArrays(); /// Should be changed to constexpr once ROOT 6 is available at STAR - enum { NAllPicoArrays = 20}; + enum { NAllPicoArrays = 23}; /// Names of the TBranches in the TTree/File static const char* picoArrayNames[NAllPicoArrays]; @@ -32,8 +32,9 @@ class StPicoArrays { enum TypeIndex { Event=0, Track, EmcTrigger, MtdTrigger, BTowHit, BTofHit, MtdHit, BbcHit, EpdHit, FmsHit, BEmcPidTraits, BTofPidTraits, MtdPidTraits, TrackCovMatrix, - BEmcSmdEHit, BEmcSmdPHit, ETofHit, ETofPidTraits, - McVertex, McTrack }; + BEmcSmdEHit, BEmcSmdPHit, ETofHit, ETofPidTraits, + McVertex, McTrack, + FwdTrack, FcsHit, FcsCluster }; }; #endif diff --git a/StRoot/StPicoEvent/StPicoDst.cxx b/StRoot/StPicoEvent/StPicoDst.cxx index 7c243deed22..920e1e781ca 100644 --- a/StRoot/StPicoEvent/StPicoDst.cxx +++ b/StRoot/StPicoEvent/StPicoDst.cxx @@ -19,6 +19,7 @@ #include "StPicoBEmcSmdPHit.h" #include "StPicoETofHit.h" #include "StPicoETofPidTraits.h" +#include "StPicoFwdTrack.h" #include "StPicoMcVertex.h" #include "StPicoMcTrack.h" #include "StPicoDst.h" //MUST be the last one @@ -328,3 +329,19 @@ void StPicoDst::printETofPidTraits() { LOG_INFO << endm; } +//_________________ +void StPicoDst::printFwdTracks() { + if(numberOfFwdTracks() == 0) { + LOG_INFO << "No Fwd tracks found!" << endm; + return; + } + + LOG_INFO << "\n+++++++++ fwd track list ( " << numberOfFwdTracks() << " entries )\n\n"; + for(UInt_t iTrk=0; iTrkPrint(); + LOG_INFO << "\n"; + } + + LOG_INFO << endm; +} diff --git a/StRoot/StPicoEvent/StPicoDst.h b/StRoot/StPicoEvent/StPicoDst.h index 7448d35b7ec..129df01e6e3 100644 --- a/StRoot/StPicoEvent/StPicoDst.h +++ b/StRoot/StPicoEvent/StPicoDst.h @@ -33,6 +33,9 @@ class StPicoBEmcSmdEHit; class StPicoBEmcSmdPHit; class StPicoETofHit; class StPicoETofPidTraits; +class StPicoFwdTrack; +class StPicoFcsHit; +class StPicoFcsCluster; class StPicoMcVertex; class StPicoMcTrack; @@ -93,6 +96,12 @@ class StPicoDst { static StPicoBEmcSmdPHit* bemcSmdPHit(Int_t i) { return (StPicoBEmcSmdPHit*)picoArrays[StPicoArrays::BEmcSmdPHit]->UncheckedAt(i); } /// Return pointer to i-th etof hit static StPicoETofHit* etofHit(Int_t i) { return (StPicoETofHit*)picoArrays[StPicoArrays::ETofHit]->UncheckedAt(i); } + /// Return pointer to i-th fwd track + static StPicoFwdTrack* fwdTrack(Int_t i) { return (StPicoFwdTrack*)picoArrays[StPicoArrays::FwdTrack]->UncheckedAt(i); } + /// Return pointer to i-th fcs Hit + static StPicoFcsHit* fcsHit(Int_t i) { return (StPicoFcsHit*)picoArrays[StPicoArrays::FcsHit]->UncheckedAt(i); } + /// Return pointer to i-th fcs Cluster + static StPicoFcsCluster* fcsCluster(Int_t i) { return (StPicoFcsCluster*)picoArrays[StPicoArrays::FcsCluster]->UncheckedAt(i); } /// Return pointer to i-th etof pidTraits static StPicoETofPidTraits* etofPidTraits(Int_t i) { return (StPicoETofPidTraits*)picoArrays[StPicoArrays::ETofPidTraits]->UncheckedAt(i); } /// Return pointer to i-th MC vertex @@ -134,6 +143,12 @@ class StPicoDst { static UInt_t numberOfETofHits() { return picoArrays[StPicoArrays::ETofHit]->GetEntriesFast(); } /// Return number of ETOF PID traits static UInt_t numberOfETofPidTraits() { return picoArrays[StPicoArrays::ETofPidTraits]->GetEntriesFast(); } + /// Return number of Fwd Tracks + static UInt_t numberOfFwdTracks() { return picoArrays[StPicoArrays::FwdTrack]->GetEntriesFast(); } + /// Return number of FcsHits + static UInt_t numberOfFcsHits() { return picoArrays[StPicoArrays::FcsHit]->GetEntriesFast(); } + /// Return number of FcsClusters + static UInt_t numberOfFcsClusters() { return picoArrays[StPicoArrays::FcsCluster]->GetEntriesFast(); } /// Return number of MC vertices static UInt_t numberOfMcVertices() { return picoArrays[StPicoArrays::McVertex]->GetEntriesFast(); } /// Return number of MC tracks @@ -169,6 +184,8 @@ class StPicoDst { static void printETofHits(); /// Print ETOF PID trait info static void printETofPidTraits(); + /// Print Fwd track info + static void printFwdTracks(); /// Print MC vertex info static void printMcVertices(); /// Print MC track info diff --git a/StRoot/StPicoEvent/StPicoDstLinkDef.h b/StRoot/StPicoEvent/StPicoDstLinkDef.h index c81c8b95ef2..9a69d010579 100644 --- a/StRoot/StPicoEvent/StPicoDstLinkDef.h +++ b/StRoot/StPicoEvent/StPicoDstLinkDef.h @@ -26,6 +26,9 @@ #pragma link C++ class StPicoDstReader+; #pragma link C++ class StPicoETofHit+; #pragma link C++ class StPicoETofPidTraits+; +#pragma link C++ class StPicoFwdTrack+; +#pragma link C++ class StPicoFcsHit+; +#pragma link C++ class StPicoFcsCluster+; #pragma link C++ class StPicoDst+; // StarClassLibrary adopted classes diff --git a/StRoot/StPicoEvent/StPicoDstReader.cxx b/StRoot/StPicoEvent/StPicoDstReader.cxx index 8a388e9f5ee..2222fa89a28 100644 --- a/StRoot/StPicoEvent/StPicoDstReader.cxx +++ b/StRoot/StPicoEvent/StPicoDstReader.cxx @@ -30,6 +30,9 @@ #include "StPicoBEmcSmdPHit.h" #include "StPicoETofHit.h" #include "StPicoETofPidTraits.h" +#include "StPicoFwdTrack.h" +#include "StPicoFcsHit.h" +#include "StPicoFcsCluster.h" #include "StPicoMcVertex.h" #include "StPicoMcTrack.h" #include "StPicoArrays.h" @@ -131,6 +134,9 @@ void StPicoDstReader::streamerOff() { StPicoBEmcSmdPHit::Class()->IgnoreTObjectStreamer(); StPicoETofHit::Class()->IgnoreTObjectStreamer(); StPicoETofPidTraits::Class()->IgnoreTObjectStreamer(); + StPicoFwdTrack::Class()->IgnoreTObjectStreamer(); + StPicoFcsHit::Class()->IgnoreTObjectStreamer(); + StPicoFcsCluster::Class()->IgnoreTObjectStreamer(); StPicoMcVertex::Class()->IgnoreTObjectStreamer(); StPicoMcTrack::Class()->IgnoreTObjectStreamer(); } diff --git a/StRoot/StPicoEvent/StPicoFcsCluster.cxx b/StRoot/StPicoEvent/StPicoFcsCluster.cxx new file mode 100644 index 00000000000..62b3386c013 --- /dev/null +++ b/StRoot/StPicoEvent/StPicoFcsCluster.cxx @@ -0,0 +1,39 @@ +#include "StPicoFcsCluster.h" +#include +#include "StPicoMessMgr.h" + +// ROOT headers +#include "TMath.h" + +ClassImp(StPicoFcsCluster) + +StPicoFcsCluster::StPicoFcsCluster() : TObject() { + /* No Op*/ +} + +StPicoFcsCluster::StPicoFcsCluster(const StPicoFcsCluster &clu){ + mId=clu.mId; + mDetectorId=clu.mDetectorId; + mCategory=clu.mCategory; + mNTowers=clu.mNTowers; + mX=clu.mX; + mY=clu.mY; + mSigmaMin=clu.mSigmaMin; + mSigmaMax=clu.mSigmaMax; + mTheta=clu.mTheta; + mChi2Ndf1Photon=clu.mChi2Ndf1Photon; + mChi2Ndf2Photon=clu.mChi2Ndf2Photon; + mFourMomentumX=clu.mFourMomentumX; + mFourMomentumY=clu.mFourMomentumY; + mFourMomentumZ=clu.mFourMomentumZ; + mFourMomentumT=clu.mFourMomentumT; +} + +StPicoFcsCluster::~StPicoFcsCluster(){ + +} + +//_________________ +void StPicoFcsCluster::Print(const Char_t* option __attribute__((unused))) const { + +} diff --git a/StRoot/StPicoEvent/StPicoFcsCluster.h b/StRoot/StPicoEvent/StPicoFcsCluster.h new file mode 100644 index 00000000000..4160cef1040 --- /dev/null +++ b/StRoot/StPicoEvent/StPicoFcsCluster.h @@ -0,0 +1,80 @@ +/*************************************************************************** + * + * Author: jdb, Feb 2022 + *************************************************************************** + * + * Description: StPicoFcsCluster stores the Fcs Clusters + * + **************************************************************************/ +#ifndef StPicoFcsCluster_hh +#define StPicoFcsCluster_hh + +#include +#include +#include "TVector3.h" +#include "TLorentzVector.h" + + +class StPicoFcsCluster : public TObject { + +public: + /// Constructor + StPicoFcsCluster( ); + /// Copy constructor + StPicoFcsCluster(const StPicoFcsCluster &fwdTrack); + /// Destructor + virtual ~StPicoFcsCluster(); + + virtual void Print(const Char_t *option = "") const; + /// Return unique Id of the track + Int_t id() const { return mId; } + unsigned short detectorId() const { return mDetectorId; } + int category() const { return mCategory; } + int nTowers() const { return mNTowers; } + float energy() const { return mFourMomentumT; } // Energy + float x() const { return mX; } // Mean x ("center of gravity") in local grid coordinate (1st moment). + float y() const { return mY; } // Mean y ("center of gravity") in local grid coordinate (1st moment). + float sigmaMax() const { return mSigmaMax; } // Maximum 2nd moment (along major axis). + float sigmaMin() const { return mSigmaMin; } // Minimum 2nd moment. + float theta() const { return mTheta; } // Angle in x-y plane that defines the direction of least-2nd-sigma + float chi2Ndf1Photon() const { return mChi2Ndf1Photon; } // chi^2/ndf for 1-photon fit to the cluster. + float chi2Ndf2Photon() const { return mChi2Ndf2Photon; } // chi^2/ndf for 2-photon fit to the cluster. + const TLorentzVector fourMomentum() const { return TLorentzVector( mFourMomentumX, mFourMomentumY, mFourMomentumZ, mFourMomentumT ); } // Cluster four-momentum (px, py, pz, E) + + void setId(int cluid) { mId = (UShort_t)cluid; } + void setDetectorId(unsigned short detector) { mDetectorId=(UShort_t)detector; } + void setCategory(int catag) { mCategory = catag; } + void setNTowers(int numbTower) { mNTowers = (UShort_t)numbTower; } + void setEnergy(float energy) { mFourMomentumT = energy; } + void setX(float x0) { mX = x0; } + void setY(float y0) { mY = y0; } + void setSigmaMin(float sigmaMin) { mSigmaMin = sigmaMin; } + void setSigmaMax(float sigmaMax) { mSigmaMax = sigmaMax; } + void setTheta(float theta) { mTheta = theta; } + void setChi2Ndf1Photon(float chi2ndfph1) { mChi2Ndf1Photon = chi2ndfph1; } + void setChi2Ndf2Photon(float chi2ndfph2) { mChi2Ndf2Photon = chi2ndfph2;} + void setFourMomentum(float px, float py, float pz, float e) { mFourMomentumX = px; mFourMomentumY = py; mFourMomentumZ = pz; mFourMomentumT = e; } + void setFourMomentum(TLorentzVector p4) { mFourMomentumX = p4.X(); mFourMomentumY = p4.Y(); mFourMomentumZ = p4.Z(); mFourMomentumT = p4.T(); } + +protected: + UShort_t mId=0; // Eventwise cluster ID + UShort_t mDetectorId=0; // Detector starts from 1 + Int_t mCategory=0; // Category of cluster (see StMuFcsClusterCategory) + UShort_t mNTowers=0; // Number of non-zero-energy tower hits in the cluster + Float_t mX=0.0; // Mean x ("center of gravity") in local grid coordinate (1st moment) + Float_t mY=0.0; // Mean y ("center of gravity") in local grid coordinate (1st moment) + Float_t mSigmaMin=0.0; // Minimum 2nd moment + Float_t mSigmaMax=0.0; // Maximum 2nd moment (along major axis) + Float_t mTheta=0.0; //Angle in x-y plane that defines the direction of least-2nd-sigma + Float_t mChi2Ndf1Photon=0.0; // χ2 / ndf for 1-photon fit + Float_t mChi2Ndf2Photon=0.0; // χ2 / ndf for 2-photon fit + Float_t mFourMomentumX=0.0; + Float_t mFourMomentumY=0.0; + Float_t mFourMomentumZ=0.0; + Float_t mFourMomentumT=0.0; + + ClassDef(StPicoFcsCluster, 2) +}; + +#endif + diff --git a/StRoot/StPicoEvent/StPicoFcsHit.cxx b/StRoot/StPicoEvent/StPicoFcsHit.cxx new file mode 100644 index 00000000000..f372e59709d --- /dev/null +++ b/StRoot/StPicoEvent/StPicoFcsHit.cxx @@ -0,0 +1,27 @@ +#include "StPicoFcsHit.h" +#include +#include "StPicoMessMgr.h" + +// ROOT headers +#include "TMath.h" + +ClassImp(StPicoFcsHit) + +StPicoFcsHit::StPicoFcsHit() : TObject() { +} + +StPicoFcsHit::StPicoFcsHit(const StPicoFcsHit &hit){ + mIndex=hit.mIndex; + mDetectorId=hit.mDetectorId; + mId=hit.mId; + mFourMomentumX=hit.mFourMomentumX; + mFourMomentumY=hit.mFourMomentumY; + mFourMomentumZ=hit.mFourMomentumZ; + mFourMomentumT=hit.mFourMomentumT; +} + +StPicoFcsHit::~StPicoFcsHit(){ +} + +void StPicoFcsHit::Print(const Char_t* option __attribute__((unused))) const { +} diff --git a/StRoot/StPicoEvent/StPicoFcsHit.h b/StRoot/StPicoEvent/StPicoFcsHit.h new file mode 100644 index 00000000000..265b4ae5e44 --- /dev/null +++ b/StRoot/StPicoEvent/StPicoFcsHit.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * + * Author: jdb, Feb 2022 + *************************************************************************** + * + * Description: StPicoFcsHit stores the Fcs Hits + * + **************************************************************************/ +#ifndef StPicoFcsHit_hh +#define StPicoFcsHit_hh + +#include +#include +#include "TVector3.h" +#include "TLorentzVector.h" + +class StPicoFcsHit : public TObject { + +public: + /// Constructor + StPicoFcsHit(); + /// Copy constructor + StPicoFcsHit(const StPicoFcsHit &fwdTrack); + /// Destructor + virtual ~StPicoFcsHit(); + + virtual void Print(const Char_t *option = "") const; + Int_t index() const { return mIndex; } // Return unique Index of the hit + unsigned short detectorId() const { return mDetectorId; } + Int_t id() const { return mId; } // Id of the hit winthin detectorId + float energy() const { return mFourMomentumT; } // Energy + const TLorentzVector fourMomentum() const { return TLorentzVector( mFourMomentumX, mFourMomentumY, mFourMomentumZ, mFourMomentumT ); } // Hit four-momentum (px, py, pz, E) + + void setIndex(int index) { mIndex = (UShort_t)index; } + void setDetectorId(unsigned short detector) { mDetectorId=(UShort_t)detector; } + void setId(int id) { mIndex = (UShort_t)id; } + void setFourMomentum(float px, float py, float pz, float e) { mFourMomentumX = px; mFourMomentumY = py; mFourMomentumZ = pz; mFourMomentumT = e; } + void setFourMomentum(TLorentzVector p4) { mFourMomentumX = p4.X(); mFourMomentumY = p4.Y(); mFourMomentumZ = p4.Z(); mFourMomentumT = p4.T(); } + +protected: + UShort_t mIndex=0; // Eventwise Hit Index + UShort_t mDetectorId=0; // DetectorId + UShort_t mId=0; // Id of the hit winthin a detectorId + Float_t mFourMomentumX=0.0; // Four momentum component X + Float_t mFourMomentumY=0.0; // Four momentum component Y + Float_t mFourMomentumZ=0.0; // Four momentum component Z + Float_t mFourMomentumT=0.0; // Four momentum component T + + ClassDef(StPicoFcsHit, 1) +}; + +#endif + diff --git a/StRoot/StPicoEvent/StPicoFwdTrack.cxx b/StRoot/StPicoEvent/StPicoFwdTrack.cxx new file mode 100644 index 00000000000..a381dc9fc64 --- /dev/null +++ b/StRoot/StPicoEvent/StPicoFwdTrack.cxx @@ -0,0 +1,55 @@ +#include "StPicoFwdTrack.h" +#include +#include "StPicoMessMgr.h" + +// ROOT headers +#include "TMath.h" + +ClassImp(StPicoFwdTrack) + +StPicoFwdTrack::StPicoFwdTrack() : TObject() { + /* No Op*/ +} + +StPicoFwdTrack::StPicoFwdTrack(const StPicoFwdTrack &fwdTrack){ + mId = fwdTrack.mId; + mNumberOfSeedPoints = fwdTrack.mNumberOfSeedPoints; + mNumberOfFitPoints = fwdTrack.mNumberOfFitPoints; + mChi2 = fwdTrack.mChi2; + + mMomentumX = fwdTrack.mMomentumX; + mMomentumY = fwdTrack.mMomentumY; + mMomentumZ = fwdTrack.mMomentumZ; + mStatus = fwdTrack.mStatus; + + mIdTruth = fwdTrack.mIdTruth; + mQATruth = fwdTrack.mQATruth; + + for ( size_t i = 0 ; i < fwdTrack.mEcalMatchIndex.size(); i++ ){ + addEcalCluster( fwdTrack.mEcalMatchIndex[i] ); + } + for ( size_t i = 0 ; i < fwdTrack.mHcalMatchIndex.size(); i++ ){ + addHcalCluster( fwdTrack.mHcalMatchIndex[i] ); + } +} + +StPicoFwdTrack::~StPicoFwdTrack(){ + +} + +//_________________ +void StPicoFwdTrack::Print(const Char_t* option __attribute__((unused))) const { + LOG_INFO << " chi2: " << chi2() << "\n" + << "pMom: " << momentum().X() << " " << momentum().Y() << " " << momentum().Z() << "\n" + << "nHitsFit: " << numberOfFitPoints() + << " numberOfSeedPoints: " << numberOfSeedPoints() << "\n" + // << "idTruth: " << idTruth() << " qaTruth: " << qaTruth() << "\n" + << endm; +} + +//_________________ +void StPicoFwdTrack::setChi2(Float_t chi2) { + mChi2 = ( (chi2 * 1000.) > std::numeric_limits::max() ? + std::numeric_limits::max() : + (UShort_t)( TMath::Nint( chi2 * 1000. ) ) ); +} \ No newline at end of file diff --git a/StRoot/StPicoEvent/StPicoFwdTrack.h b/StRoot/StPicoEvent/StPicoFwdTrack.h new file mode 100644 index 00000000000..40fc99bdc0d --- /dev/null +++ b/StRoot/StPicoEvent/StPicoFwdTrack.h @@ -0,0 +1,110 @@ +/*************************************************************************** + * + * Author: jdb, Feb 2022 + *************************************************************************** + * + * Description: StPicoFwdTrack stores the Forward tracks built from Fst and Ftt + * + **************************************************************************/ +#ifndef StPicoFwdTrack_hh +#define StPicoFwdTrack_hh + +#include +#include +#include "TVector3.h" +#include "TRefArray.h" + + +class StPicoFwdTrack : public TObject { + +public: + /// Constructor + StPicoFwdTrack( ); + /// Copy constructor + StPicoFwdTrack(const StPicoFwdTrack &fwdTrack); + /// Destructor + virtual ~StPicoFwdTrack(); + + virtual void Print(const Char_t *option = "") const; + /// Return unique Id of the track + Int_t id() const { return mId; } + /// Return chi2 of the track + Float_t chi2() const { return mChi2 / 1000.f; } + /// Return momentum (GeV/c) + TVector3 momentum() const { return TVector3( mMomentumX, mMomentumY, mMomentumZ ); } + /// Return charge of the track (encoded in nHitsFit as: nHitsFit * charge) + Short_t charge() const { return (mNumberOfFitPoints > 0) ? 1 : -1; } + /// Quality of the fit (from status) + bool didFitConverge() const { return (mStatus >= 1); } + bool didFitConvergeFully() const { return (mStatus >= 2); } + /// Return if the track fit converged + Char_t status() const { return mStatus; } + /// Index of the corresponding MC track + Int_t idTruth() const { return mIdTruth; } + /// Qualtiy of the MC track + Int_t qaTruth() const { return mQATruth; } + + // Number of fit points used by GenFit + Int_t numberOfFitPoints() const { return mNumberOfFitPoints; } + // unsigned int numberOfPossibleFitPoints() const; + + // Number of points used in the track seed step + Int_t numberOfSeedPoints() const { return mNumberOfSeedPoints; } + + void setId( Int_t id) { mId = (UShort_t)id; } + void setMomentum( TVector3 mom ) { mMomentumX = mom.X(); mMomentumY = mom.Y(); mMomentumZ = mom.Z(); } + void setMomentum( double px, double py, double pz ) { mMomentumX = (Float_t)px; mMomentumY = (Float_t)py; mMomentumZ = (Float_t)pz; } + void setStatus( UChar_t status ) { mStatus = status;} + void setNumberOfSeedPoints( Int_t lNumberOfSeedPoints ) { mNumberOfSeedPoints = (UChar_t)lNumberOfSeedPoints;} + void setNumberOfFitPoints( Int_t lNumberOfFitPoints ) { mNumberOfFitPoints = (Char_t)lNumberOfFitPoints;} + void setChi2(Float_t chi2); + void addEcalCluster( UChar_t index ) { mEcalMatchIndex.push_back(index); } + void addHcalCluster( UChar_t index ) { mHcalMatchIndex.push_back(index); } + /// Set index of the corresonding MC track + void setMcTruth(Int_t index, Int_t qa) { mIdTruth = (UShort_t)index; mQATruth = (UShort_t)qa; } + +protected: + + // Track quality and convergence + /// Unique track ID + UShort_t mId; + /// Number of points used in seed + UChar_t mNumberOfSeedPoints; + /// Charge * nHitsFit + Char_t mNumberOfFitPoints; + /// Chi2 of the track (encoding = chi2*1000) + UShort_t mChi2; + + /// Px momentum (GeV/c) + Float_t mMomentumX; + /// Py momentum (GeV/c) + Float_t mMomentumY; + /// Pz momentum (GeV/c) + Float_t mMomentumZ; + /// convergence (0=no, 1=converge, 2=converge fully) + UChar_t mStatus; + /// DCA to primary vertex (XY) + Float_t mDCAXY; + /// DCA to primary vertex (Z) + Float_t mDCAZ; + /// Index of primary vertex used in fit (primary tracks only) + UChar_t mVtxIndex; + /// Index of the corresponding Global Track if primary, else USHRT_MAX + UShort_t mGlobalTrackIndex; + + /// ecal match index + std::vector mEcalMatchIndex; + /// hcal match index + std::vector mHcalMatchIndex; + + /// MC track id + UShort_t mIdTruth; + /// MC track quality (percentage of hits coming from corresponding MC track) + UShort_t mQATruth; + + ClassDef(StPicoFwdTrack,2) + +}; + +#endif + From 0296a7b1d1652a8911d4de31a33e4fe578c4e9e0 Mon Sep 17 00:00:00 2001 From: Daniel Brandenburg Date: Tue, 28 Jan 2025 20:47:01 -0500 Subject: [PATCH 04/10] Revert "address comments from plexos & klendathu" This reverts commit 6d24adedd3a683d1ebcd6109a9a3a6398d618fa3. --- StRoot/StEvent/StEnumerations.h | 4 +- StRoot/StEvent/StFstConsts.h | 4 +- StRoot/StEvent/StFwdTrack.cxx | 9 +- StRoot/StEvent/StFwdTrack.h | 39 +- StRoot/StEvent/StFwdTrackCollection.cxx | 4 +- StRoot/StEvent/StFwdTrackCollection.h | 2 +- StRoot/StEvent/StVertex.h | 2 - StRoot/StFwdTrackMaker/StFwdClosureMaker.cxx | 524 ----- StRoot/StFwdTrackMaker/StFwdClosureMaker.h | 72 - StRoot/StFwdTrackMaker/StFwdQAMaker.cxx | 464 +---- StRoot/StFwdTrackMaker/StFwdQAMaker.h | 35 - StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx | 1710 ++++++++++------- StRoot/StFwdTrackMaker/StFwdTrackMaker.h | 259 ++- .../include/Tracker/FitterUtils.h | 144 -- .../include/Tracker/FwdDataSource.h | 26 +- .../include/Tracker/FwdGeomUtils.h | 23 +- .../StFwdTrackMaker/include/Tracker/FwdHit.h | 50 +- .../include/Tracker/FwdTracker.h | 1684 +++++++--------- .../include/Tracker/ObjExporter.h | 74 +- .../include/Tracker/TrackFitter.h | 946 ++++++--- StRoot/StFwdTrackMaker/macro/build_geom.C | 5 +- StRoot/StFwdTrackMaker/macro/daq/daq_track.C | 69 +- StRoot/StFwdTrackMaker/macro/daq/submit.xml | 5 + StRoot/StFwdTrackMaker/macro/event/ana.C | 42 - StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C | 137 -- StRoot/StFwdTrackMaker/macro/mudst/mudst.C | 130 -- StRoot/StFwdTrackMaker/macro/mudst/pico.C | 602 ------ .../macro/mudst/submit_pico_run22pp.xml | 43 - StRoot/StFwdTrackMaker/macro/qa/mudst.C | 78 - StRoot/StFwdTrackMaker/macro/qa/qa.C | 281 --- StRoot/StFwdTrackMaker/macro/shell.C | 9 - StRoot/StFwdTrackMaker/macro/sim/close.C | 108 -- StRoot/StFwdTrackMaker/macro/sim/fast.C | 145 -- StRoot/StFwdTrackMaker/macro/sim/gen | 17 - StRoot/StFwdTrackMaker/macro/sim/gen.C | 87 +- .../macro/sim/ideal-sim-fst-seed | 2 - .../macro/sim/ideal-sim-ftt-seed | 2 - StRoot/StFwdTrackMaker/macro/sim/jpsi | 16 - StRoot/StFwdTrackMaker/macro/sim/jpsi.C | 225 --- StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C | 181 -- StRoot/StFwdTrackMaker/macro/sim/lambda.C | 191 -- .../macro/sim/real-sim-fst-seed | 2 - .../macro/sim/real-sim-ftt-seed | 2 - StRoot/StFwdTrackMaker/macro/sim/sim.C | 242 --- .../macro/sim/single_particle_gun.C | 28 - StRoot/StFwdTrackMaker/macro/viz.C | 210 +- StRoot/StFwdTrackMaker/macro/viz2.C | 600 ------ StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx | 24 +- StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx | 26 +- StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h | 77 +- StRoot/StPicoDstMaker/StPicoDstMaker.cxx | 112 -- StRoot/StPicoDstMaker/StPicoDstMaker.h | 6 - StRoot/StPicoEvent/StPicoArrays.cxx | 21 +- StRoot/StPicoEvent/StPicoArrays.h | 7 +- StRoot/StPicoEvent/StPicoDst.cxx | 17 - StRoot/StPicoEvent/StPicoDst.h | 17 - StRoot/StPicoEvent/StPicoDstLinkDef.h | 3 - StRoot/StPicoEvent/StPicoDstReader.cxx | 6 - StRoot/StPicoEvent/StPicoFcsCluster.cxx | 39 - StRoot/StPicoEvent/StPicoFcsCluster.h | 80 - StRoot/StPicoEvent/StPicoFcsHit.cxx | 27 - StRoot/StPicoEvent/StPicoFcsHit.h | 53 - StRoot/StPicoEvent/StPicoFwdTrack.cxx | 55 - StRoot/StPicoEvent/StPicoFwdTrack.h | 110 -- 64 files changed, 2838 insertions(+), 7376 deletions(-) delete mode 100644 StRoot/StFwdTrackMaker/StFwdClosureMaker.cxx delete mode 100644 StRoot/StFwdTrackMaker/StFwdClosureMaker.h delete mode 100644 StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h delete mode 100755 StRoot/StFwdTrackMaker/macro/event/ana.C delete mode 100644 StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C delete mode 100755 StRoot/StFwdTrackMaker/macro/mudst/mudst.C delete mode 100755 StRoot/StFwdTrackMaker/macro/mudst/pico.C delete mode 100644 StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml delete mode 100755 StRoot/StFwdTrackMaker/macro/qa/mudst.C delete mode 100755 StRoot/StFwdTrackMaker/macro/qa/qa.C delete mode 100755 StRoot/StFwdTrackMaker/macro/shell.C delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/close.C delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/fast.C delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/gen mode change 100755 => 100644 StRoot/StFwdTrackMaker/macro/sim/gen.C delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/ideal-sim-fst-seed delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/ideal-sim-ftt-seed delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/jpsi delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/jpsi.C delete mode 100644 StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/lambda.C delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/real-sim-fst-seed delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/real-sim-ftt-seed delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/sim.C delete mode 100755 StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C mode change 100755 => 100644 StRoot/StFwdTrackMaker/macro/viz.C delete mode 100755 StRoot/StFwdTrackMaker/macro/viz2.C delete mode 100644 StRoot/StPicoEvent/StPicoFcsCluster.cxx delete mode 100644 StRoot/StPicoEvent/StPicoFcsCluster.h delete mode 100644 StRoot/StPicoEvent/StPicoFcsHit.cxx delete mode 100644 StRoot/StPicoEvent/StPicoFcsHit.h delete mode 100644 StRoot/StPicoEvent/StPicoFwdTrack.cxx delete mode 100644 StRoot/StPicoEvent/StPicoFwdTrack.h diff --git a/StRoot/StEvent/StEnumerations.h b/StRoot/StEvent/StEnumerations.h index 2f35ca7162a..04ff9802f83 100644 --- a/StRoot/StEvent/StEnumerations.h +++ b/StRoot/StEvent/StEnumerations.h @@ -400,9 +400,7 @@ enum StVertexId {kUndefinedVtxId = kUndefinedVertexIdentifier, kFtpcEastCalVtxId = kFtpcEastCalibrationVertexIdentifier, kFtpcWestCalVtxId = kFtpcWestCalibrationVertexIdentifier, kBEAMConstrVtxId, - kRejectedVtxId, - kFwdVtxId - }; + kRejectedVtxId}; /*! * \enum StRichPidFlag diff --git a/StRoot/StEvent/StFstConsts.h b/StRoot/StEvent/StFstConsts.h index f91d8214c39..fd84cc5ed12 100644 --- a/StRoot/StEvent/StFstConsts.h +++ b/StRoot/StEvent/StFstConsts.h @@ -52,8 +52,8 @@ const float kFstrStart[kFstNumRStripsPerWedge]= {5.000, 7.875, 10.750, 13.625, 1 const float kFstrStop[kFstNumRStripsPerWedge] = {7.875, 10.750, 136.25, 16.500, 19.375, 22.250, 25.125, 28.000}; // in cm //general APV chip constants -const unsigned char kFstNumTimeBins = 3; // 9 time bins for ADC sampling (maximum time bin number, 3 or 9) -const unsigned char kFstDefaultTimeBin = 1; // the default time bin number (2nd time bin) for FST raw hits +const unsigned char kFstNumTimeBins = 9; // 9 time bins for ADC sampling (maximum time bin number, 3 or 9) +const unsigned char kFstDefaultTimeBin = 2; // the default time bin number (2nd time bin) for FST raw hits const int kFstMaxAdc = 4096; // ADC value should be less than 4096 (12 bits ADC) #endif diff --git a/StRoot/StEvent/StFwdTrack.cxx b/StRoot/StEvent/StFwdTrack.cxx index 2cbb5dca531..1e9a3ef519f 100644 --- a/StRoot/StEvent/StFwdTrack.cxx +++ b/StRoot/StEvent/StFwdTrack.cxx @@ -2,9 +2,14 @@ #include "StEvent/StFcsCluster.h" #include "St_base/StMessMgr.h" -StFwdTrack::StFwdTrack() {} +StFwdTrack::StFwdTrack() { -StFwdTrack::~StFwdTrack() {} +} + +StFwdTrack::~StFwdTrack() { + mEcalClusters.clear(); + mHcalClusters.clear(); +} /* momentum diff --git a/StRoot/StEvent/StFwdTrack.h b/StRoot/StEvent/StFwdTrack.h index 7b4724b2022..f74ef75ed8e 100644 --- a/StRoot/StEvent/StFwdTrack.h +++ b/StRoot/StEvent/StFwdTrack.h @@ -169,27 +169,32 @@ class StFwdTrack : public StObject { protected: - // Track quality and convergence - bool mDidFitConverge; // did the fit converge - bool mDidFitConvergeFully; // did the fit converge fully (forward and backward) - short mNumberOfFailedPoints; // number of failed points - short mNumberOfSeedPoints; // number of seed points - short mNumberOfFitPoints; // number of fit points (seeds + vertex) - float mChi2; // chi2 of the fit - float mNDF; // number of degrees of freedom - float mPval; // p-value of the fit - short mCharge; // charge of the track - StThreeVectorD mPrimaryMomentum; // momentum at the primary vertex - StPtrVecFcsCluster mEcalClusters; // ECAL clusters - StPtrVecFcsCluster mHcalClusters; // HCAL clusters - UShort_t mIdTruth; // MC track id - UShort_t mQATruth; // MC track quality (percentage of hits coming from corresponding MC track) + + // Track quality and convergence + bool mDidFitConverge; + bool mDidFitConvergeFully; + short mNumberOfFailedPoints; + short mNumberOfSeedPoints; + short mNumberOfFitPoints; + float mChi2; + float mNDF; + float mPval; + short mCharge; + StThreeVectorD mPrimaryMomentum; + StPtrVecFcsCluster mEcalClusters; + StPtrVecFcsCluster mHcalClusters; + /// MC track id + UShort_t mIdTruth; + /// MC track quality (percentage of hits coming from corresponding MC track) + UShort_t mQATruth; float mDCA[3]; // DCA to the primary vertex - UChar_t mVtxIndex; // index of the primary vertex + UChar_t mVtxIndex; + + + ClassDef(StFwdTrack,4) - ClassDef(StFwdTrack,3) }; #endif diff --git a/StRoot/StEvent/StFwdTrackCollection.cxx b/StRoot/StEvent/StFwdTrackCollection.cxx index ff0577b79e6..ca09d7130b8 100644 --- a/StRoot/StEvent/StFwdTrackCollection.cxx +++ b/StRoot/StEvent/StFwdTrackCollection.cxx @@ -17,8 +17,8 @@ ClassImp(StFwdTrackCollection) StFwdTrackCollection::~StFwdTrackCollection(){ for (unsigned int i=0; i mFitter = nullptr; -std::unique_ptr mBField; -std::map< string, TH1* > mHistograms; - -TH1 * addHistogram1D( string name, string title, int nbins, double min, double max ){ - TH1 * h = new TH1F( name.c_str(), title.c_str(), nbins, min, max ); - mHistograms[name] = h; - return h; -} - -TH2 * addHistogram2D( string name, string title, int nbinsX, double minX, double maxX, int nbinsY, double minY, double maxY ){ - TH2 * h = new TH2F( name.c_str(), title.c_str(), nbinsX, minX, maxX, nbinsY, minY, maxY ); - mHistograms[name] = h; - return h; -} - -TH1 * getHistogram1D( string name ){ - if ( mHistograms.count(name) ) - return mHistograms[name]; - assert( false && "Histogram not found" ); - return nullptr; -} -TH2 * getHistogram2D( string name ){ - return dynamic_cast( getHistogram1D(name) ); -} - -struct Point { - double x, y; -}; - -// Function to calculate the determinant of a 2x2 matrix -double determinant(double a, double b, double c, double d) { - return a * d - b * c; -} - -// Function to compute the curvature of a circle given 3 points -double computeCurvature(const Point& p1, const Point& p2, const Point& p3) { - // Calculate the lengths of the sides of the triangle - double A = std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2)); - double B = std::sqrt(std::pow(p3.x - p2.x, 2) + std::pow(p3.y - p2.y, 2)); - double C = std::sqrt(std::pow(p1.x - p3.x, 2) + std::pow(p1.y - p3.y, 2)); - - // Calculate the determinant of the matrix formed by the points - double det = determinant(p2.x - p1.x, p2.y - p1.y, p3.x - p1.x, p3.y - p1.y); - // LOG_INFO << "Det: " << det << endm; - double charge = det > 0 ? -1 : 1; - // Area of the triangle formed by the three points - double area = std::abs(det) / 2.0; - - if (area == 0) { - std::cerr << "The points are collinear, curvature is undefined." << std::endl; - return -1; // Curvature is undefined for collinear points - } - - // Calculate the radius of the circumcircle using the formula: - // R = (A * B * C) / (4 * area) - double radius = (A * B * C) / (4 * area); - // LOG_INFO << "Radius: " << radius << endm; - // Curvature is the inverse of the radius - return charge / radius; -} - -int StFwdClosureMaker::Init() { - - /****************************************************** - * Setup GenFit - */ - // Setup the Geometry used by GENFIT - TGeoManager::Import("fGeom.root"); - gMan = gGeoManager; - // Set up the material interface and set material effects on/off from the config - genfit::MaterialEffects::getInstance()->init(new genfit::TGeoMaterialInterface()); - genfit::MaterialEffects::getInstance()->setNoEffects( true ); - // Setup the BField to use - // mBField = std::unique_ptr(new genfit::ConstField(0., 0., 5)); // 0.5 T Bz - mBField = std::unique_ptr(new StarFieldAdaptor()); - genfit::FieldManager::getInstance()->init(mBField.get()); - - // initialize the main mFitter using a KalmanFitter with reference tracks - mFitter = std::unique_ptr(new genfit::KalmanFitterRefTrack( - /*maxIterations = */ mMaxIt, - /*deltaPval = */ mPVal, - /*blowUpFactor = */ mBlowUp - )); - - mFitter->setRelChi2Change( mRelChi2 ); - - // Setup the histograms - addHistogram2D( "PtCorrelation", "PtCorrelation; MC; RC;", 100, 0, 1, 100, 0, 1 ); - addHistogram1D( "PtResolution", "PtResolution; (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, -5, 5 ); - addHistogram1D( "CurveResolution", "CurveResolution; (1/p_{T}^{MC} - 1/p_{T}^{RC}) / 1/p_{T}^{MC};", 100, -5, 5 ); - 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 ); - addHistogram2D( "PtResolutionVsPt", "PtResolution; Pt (GeV/c); (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, 0, 2.0, 100, -5, 5 ); - addHistogram1D( "PointCurvePtResolution", "PointCurve PtResolution; (p_{T}^{MC} - p_{T}^{RC}) / p_{T}^{MC};", 100, -5, 5 ); - addHistogram1D( "PointCurveCurveResolution", "PointCurve CurveResolution; (1/p_{T}^{MC} - 1/p_{T}^{RC}) / 1/p_{T}^{MC};", 100, -5, 5 ); - - addHistogram1D( "QCurve", "QCurve; q/Pt;", 100, -5, 5 ); - addHistogram2D( "QMatrix", "QMatrix; MC; RC;", 4, -2, 2, 4, -2, 2 ); - addHistogram2D( "QidVsPt", "QMatrix; Pt; Qid;", 100, 0, 2.0, 2, -0.5, 1.5 ); - return kStOk; -} - - - -int StFwdClosureMaker::Finish() { - - getHistogram1D("PtResolution")->Draw(); - gPad->Print( "ClosurePtResolution.pdf" ); - - getHistogram1D("CurveResolution")->Draw(); - gPad->Print( "ClosureCurveResolution.pdf" ); - - getHistogram1D("PointCurvePtResolution")->Draw(); - gPad->Print( "ClosurePointCurvePtResolution.pdf" ); - - getHistogram1D("PointCurveCurveResolution")->Draw(); - gPad->Print( "ClosurePointCurveCurveResolution.pdf" ); - - TFile * fOut = new TFile(mOutFile, "RECREATE"); - fOut->cd(); - for ( auto h : mHistograms ){ - h.second->Write(); - } - - return kStOk; -} - - -int StFwdClosureMaker::Make() { - LOG_INFO << "Make (StFwdClosureMaker)" << endm; - - /***************************************************** - * Load the MC Vertex - */ - St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); - if (!g2t_vertex) - return 0; - - /***************************************************** - * Load the MC Tracks - */ - // Store the McMomentum for the first track (assuming single particle gun) - TVector3 mcMom(0,0,0); - int mcQ = 0; - // Get geant tracks - St_g2t_track *g2t_track = (St_g2t_track *)GetDataSet("geant/g2t_track"); - if (!g2t_track) - return 0; - - LOG_DEBUG << g2t_track->GetNRows() << " mc tracks in geant/g2t_track " << endm; - // Load the MC track info - for (int irow = 0; irow < g2t_track->GetNRows(); irow++) { - g2t_track_st *track = (g2t_track_st *)g2t_track->At(irow); - - if (0 == track) - continue; - - int track_id = track->id; - float pt2 = track->p[0] * track->p[0] + track->p[1] * track->p[1]; - float pt = std::sqrt(pt2); - float eta = track->eta; - TVector3 pp( track->p[0], track->p[1], track->p[2] ); - if ( track_id == 1 ){ - mcMom.SetXYZ( track->p[0], track->p[1], track->p[2] ); - mcQ = track->charge; - } - float phi = std::atan2(track->p[1], track->p[0]); //track->phi; - int q = track->charge; - LOG_INFO << "McTrack: " << track_id << ", pt = " << pt << ", eta = " << eta << ", phi = " << phi << ", q = " << q << endm; - } - - - - vector spoints; - - /***************************************************** - * Load the FST hits - */ - St_g2t_fts_hit *g2t_fsi_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_fsi_hit"); - if ( !g2t_fsi_hits ){ - LOG_DEBUG << "No g2t_fts_hits, cannot load FST hits from GEANT" << endm; - return 0; - } - - // reuse this to store cov mat - TMatrixDSym hitCov3(3); - const double sigXY = 0.01; - hitCov3(0, 0) = sigXY * sigXY; - hitCov3(1, 1) = sigXY * sigXY; - hitCov3(2, 2) = 0.1; - - TMatrixDSym vStripCov3(3); - vStripCov3(0, 0) = sigXY * sigXY; - vStripCov3(1, 1) = 50; - vStripCov3(2, 2) = 0.1; - - TMatrixDSym hStripCov3(3); - hStripCov3(0, 0) = 50; - hStripCov3(1, 1) = sigXY * sigXY; - hStripCov3(2, 2) = 0.1; - - /***************************************************** - * Add Primary Vertex to the track - */ - if ( g2t_vertex != nullptr ) { - // Set the MC Vertex for track fitting - g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0); - TMatrixDSym cov; - cov.ResizeTo(3, 3); - cov(0, 0) = pow(mPrimaryVertexSigXY,2); - cov(1, 1) = pow(mPrimaryVertexSigXY,2); - cov(2, 2) = pow(mPrimaryVertexSigZ, 2); - auto rhc = TVectorD( 3 ); - rhc[0] = vert->ge_x[0]; - rhc[1] = vert->ge_x[1]; - rhc[2] = vert->ge_x[2]; - auto spoint = new genfit::SpacepointMeasurement(rhc, cov, 0, 0, nullptr); - spoints.push_back(spoint); - // mForwardTracker->setEventVertex( TVector3( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ), cov ); - } - - /***************************************************** - * Add FST hits to the track - */ - for (int i = 0; i < g2t_fsi_hits->GetNRows(); i++) { - - g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_fsi_hits->At(i); - if (0 == git) - continue; // geant hit - - // int track_id = git->track_p; - int volume_id = git->volume_id; // 4, 5, 6 - int d = volume_id / 1000; // disk id - - // int plane_id = d - 4; - float x = git->x[0]; - float y = git->x[1]; - float z = git->x[2]; - - auto rhc = TVectorD( 3 ); - TVector3 rastered = raster( TVector3( x, y, z ) ); - rhc[0] = rastered.X(); - rhc[1] = rastered.Y(); - rhc[2] = rastered.Z(); - auto spoint = new genfit::SpacepointMeasurement(rhc, makeSiCovMat(TVector3( x, y, z )), 0, i+1, nullptr); - spoints.push_back(spoint); - LOG_INFO << "FST HIT: d = " << d << ", x=" << x << ", y=" << y << ", z=" << z << endm; - } - - St_g2t_fts_hit *g2t_stg_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_stg_hit"); - if (!g2t_stg_hits){ - LOG_WARN << "geant/g2t_stg_hit is empty" << endm; - return kStOk; - } - int nstg = g2t_stg_hits->GetNRows(); - - LOG_DEBUG << "This event has " << nstg << " stg hits in geant/g2t_stg_hit " << endm; - int nFttHits = 0; - for (int i = 0; i < nstg; i++) { - - g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_stg_hits->At(i); - if (0 == git) - continue; // geant hit - // int track_id = git->track_p; - int volume_id = git->volume_id; - int plane_id = (volume_id - 1) / 100; // from 1 - 16. four chambers per station - - // only use the hits on the front modules - if ( mFttMode == kPoint && volume_id % 2 ==0 ) - continue; - - float x = git->x[0]; - float y = git->x[1]; - float z = git->x[2]; - - if (plane_id < 0 || plane_id >= 4) { - continue; - } - - auto rhc = TVectorD( 3 ); - rhc[0] = x; - rhc[1] = y; - rhc[2] = z; - LOG_INFO << "FTT HIT: plane_id = " << plane_id << ", volume_d = " << volume_id << " x=" << x << ", y=" << y << ", z=" << z << endm; - - if ( kPoint == mFttMode ){ - auto spoint = new genfit::SpacepointMeasurement(rhc, hitCov3, 0, i+4, nullptr); - if ( nFttHits < mNumFttToUse ) - spoints.push_back(spoint); - } else { - if ( volume_id % 2 == 0 ){ - auto spoint = new genfit::SpacepointMeasurement(rhc, vStripCov3, 0, i+4, nullptr); - if ( nFttHits < mNumFttToUse ) - spoints.push_back(spoint); - } else { - auto spoint = new genfit::SpacepointMeasurement(rhc, hStripCov3, 0, i+4, nullptr); - if ( nFttHits < mNumFttToUse ) - spoints.push_back(spoint); - } - } - - nFttHits++; - } - - float ptCurve = 9999.0; - float qCurve = 1.0; - if ( spoints.size() >= 3 ){ - double curve = computeCurvature( {spoints[0]->getRawHitCoords()[0], spoints[0]->getRawHitCoords()[1]}, - {spoints[1]->getRawHitCoords()[0], spoints[1]->getRawHitCoords()[1]}, - {spoints[2]->getRawHitCoords()[0], spoints[2]->getRawHitCoords()[1]} ); - const double K = 0.00029979; //K depends on the units used for Bfield - const double BStrength = 5; // 0.5 T - double pt = fabs((K*BStrength)/curve); // pT from average measured curv - qCurve = curve > 0 ? 1 : -1; - ptCurve = pt; - LOG_INFO << "Curve: " << curve << ", Pt: " << pt << endm; - } - - - /***************************************************** - * Setup the Genfit Fit Track - */ - auto theTrackRep = new genfit::RKTrackRep(-13 * qCurve); - auto seedPos = TVector3(0, 0, 0); - auto seedMom = TVector3(0, 0, 10); - // seedMom.SetPtEtaPhi( ptCurve, 3.0, 0 ); - auto mFitTrack = std::make_shared(theTrackRep, seedPos, seedMom); - - LOG_INFO << "Track fit with " << spoints.size() << " space points" << endm; - try { - for ( size_t i = 0; i < spoints.size(); i++ ){ - mFitTrack->insertPoint(new genfit::TrackPoint(spoints[i], mFitTrack.get())); - } - - LOG_INFO << "Track prep = " << mFitter->isTrackPrepared( mFitTrack.get(), theTrackRep ) << endm; - - // mFitter->checkConsistency(); - mFitTrack->checkConsistency(); - // mFitter->processTrack(mFitTrack.get()); - mFitter->processTrack(mFitTrack.get()); - - mFitTrack->checkConsistency(); - mFitTrack->determineCardinalRep(); - - // mFitter->processTrack(mFitTrack.get()); - - - auto status = mFitTrack->getFitStatus(); - LOG_INFO << "Fit status: " << status->isFitConverged() << endm; - LOG_INFO << "-Fit pvalue: " << status->getPVal() << endm; - LOG_INFO << "-Fit Chi2: " << status->getChi2() << endm; - - - - auto cr = mFitTrack->getCardinalRep(); - auto p = cr->getMom( mFitTrack->getFittedState( 0, cr )); - int rcQ = status->getCharge(); - LOG_INFO << "Fit momentum: " << p.X() << ", " << p.Y() << ", " << p.Z() << endm; - LOG_INFO << "\tFit Pt: " << p.Pt() << ", eta: " << p.Eta() << ", phi: " << p.Phi() << endm; - LOG_INFO << "\tMc Pt: " << mcMom.Pt() << ", eta: " << mcMom.Eta() << ", phi: " << mcMom.Phi() << endm; - - - if (status->isFitConvergedPartially()){ - getHistogram1D("PtResolution")->Fill( (p.Pt() - mcMom.Pt()) / mcMom.Pt() ); - getHistogram1D("CurveResolution")->Fill( (1/p.Pt() - 1/mcMom.Pt()) / (1/mcMom.Pt()) ); - getHistogram1D("PtCorrelation")->Fill( mcMom.Pt(), p.Pt() ); - getHistogram1D("QCurve")->Fill( rcQ / p.Pt() ); - - getHistogram1D("PointCurvePtResolution")->Fill( (ptCurve - mcMom.Pt()) / mcMom.Pt() ); - getHistogram1D("PointCurveCurveResolution")->Fill( (1/ptCurve - 1/mcMom.Pt()) / (1/mcMom.Pt()) ); - - getHistogram2D("PtResolutionVsPt")->Fill( mcMom.Pt(), (p.Pt() - mcMom.Pt()) / mcMom.Pt() ); - getHistogram2D("CurveResolutionVsPt")->Fill( mcMom.Pt(), (1/p.Pt() - 1/mcMom.Pt()) / (1/mcMom.Pt()) ); - - getHistogram2D("QMatrix")->Fill( mcQ, rcQ ); - getHistogram2D("QidVsPt")->Fill( mcMom.Pt(), mcQ == rcQ ? 1 : 0 ); - } - else { - LOG_INFO << "Fit did not converge" << endm; - } - - - } catch (genfit::Exception &e) { - LOG_ERROR << "GenFit failed to fit track with: " << e.what() << endm; - } - - // load the space points from fst geant hits - - - // for (size_t i = 0; i < trackSeed.size(); i++) { - // auto seed = trackSeed[i]; - // TMatrixDSym cm(3); - // cm(0, 0) = 0.01; - // cm(1, 1) = 0.01; - // cm(2, 2) = 0.01; - // auto rhc = TVectorD( 3 ); - // rhc[0] = seed->getX(); - // rhc[1] = seed->getY(); - // rhc[2] = seed->getZ(); - // auto spoint = new genfit::SpacepointMeasurement(rhc, cm, 0, i, nullptr); - // spoints.push_back(spoint); - // } - - return kStOk; -} -void StFwdClosureMaker::Clear(const Option_t *opts) { - return; -} \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/StFwdClosureMaker.h b/StRoot/StFwdTrackMaker/StFwdClosureMaker.h deleted file mode 100644 index a8a9b0a452a..00000000000 --- a/StRoot/StFwdTrackMaker/StFwdClosureMaker.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef ST_FWD_CLOSURE_MAKER_H -#define ST_FWD_CLOSURE_MAKER_H - -#include "TClonesArray.h" -#ifndef __CINT__ -#include "GenFit/Track.h" -#include "StFwdTrackMaker/include/Tracker/FwdHit.h" -#include "StMuDSTMaker/COMMON/StMuFwdTrack.h" -#endif - -#include "StChain/StMaker.h" -#include "TTree.h" -#include "TVector3.h" -#include "TLorentzVector.h" -#include "StEvent/StEnumerations.h" -#include "StThreeVectorD.hh" -#include "StThreeVectorF.hh" -#include "StPhysicalHelixD.hh" - -#include - - -class StMuDstMaker; -class StMuDst; -class StMuFwdTrackCollection; -class StMuFcsCollection; -class StFwdTrackMaker; -class StEvent; - -class StFwdClosureMaker : public StMaker { - - ClassDef(StFwdClosureMaker, 0); - - public: - StFwdClosureMaker(); - ~StFwdClosureMaker(){/* nada */}; - - int Init(); - int Finish(); - int Make(); - void Clear(const Option_t *opts = ""); - -#ifndef __CINT__ - TVector3 raster(TVector3 p0); - TMatrixDSym makeSiCovMat(TVector3 hit); -#endif - - // protected: - - float mPVal = 1e-3; - float mBlowUp = 1e3; - int mMaxIt = 40; - float mRelChi2 = 0.1; - - // Primary Vertex resolutions - double mPrimaryVertexSigXY = 10.1; // in cm (e.g. 0.01 = 100 microns) - double mPrimaryVertexSigZ = 10.1; // in cm (e.g. 0.01 = 100 microns) - - // FST resolutions - double mRasterR = 3.0; - double mRasterPhi = 0.004; - - // use FTT in tracking? - int mNumFttToUse = 4; - enum FttMode { kStrip, kPoint}; - FttMode mFttMode = kPoint; - - TString mOutFile = "fwdClosure.root"; -}; - - -#endif diff --git a/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx b/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx index f356722b090..b7ce1cd225e 100644 --- a/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx +++ b/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx @@ -36,6 +36,8 @@ #include "StMuDSTMaker/COMMON/StMuMcTrack.h" #include "StMuDSTMaker/COMMON/StMuFstHit.h" +// ClassImp(FcsClusterWithStarXYZ); + /** Clear the FwdQATreeData from one event to next */ void FwdQATreeData::clear(){ header.clear(); @@ -91,12 +93,12 @@ FcsHitWithStarXYZ::FcsHitWithStarXYZ( StMuFcsHit *hit, StFcsDb *fcsDb ) { } StFwdQAMaker::StFwdQAMaker() : StMaker("fwdQAMaker"), mTreeFile(nullptr), mTree(nullptr) { - setLocalOutputFile( "./fwdHists.root" ); // default off + } int StFwdQAMaker::Init() { - mTreeFile = new TFile( mTreeFilename.Data(), "RECREATE"); + mTreeFile = new TFile("fwdtree.root", "RECREATE"); mTree = new TTree("fwd", "fwd tracking tree"); mTree->Branch("header", &mTreeData. header, 3200, 99 ); @@ -105,6 +107,7 @@ int StFwdQAMaker::Init() { mTreeData.fstPoints.createBranch(mTree, "fstHits"); mTreeData.fttPoints.createBranch(mTree, "fttPoints"); mTreeData.fttClusters.createBranch(mTree, "fttClusters"); + mTreeData.fstPoints.createBranch(mTree, "fstPoints"); mTreeData.wcal.createBranch(mTree, "wcalClusters"); mTreeData.hcal.createBranch(mTree, "hcalClusters"); @@ -114,63 +117,8 @@ int StFwdQAMaker::Init() { mTreeData.reco.createBranch(mTree, "reco"); mTreeData.seeds.createBranch(mTree, "seeds"); - - - - //========================================================================================================= adding histograms (new) - AddHist( mHists["fwdMultFailed"] = new TH1F("fwdMultFailed", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); - AddHist( mHists["fwdMultAll"] = new TH1F("fwdMultAll", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); - AddHist( mHists["fwdMultGood"] = new TH1F("fwdMultGood", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); - AddHist( mHists["fwdMultFST"] = new TH1F("fwdMultFST", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); - AddHist( mHists["nHitsFit"] = new TH1F("nHitsFit", ";nHitsFit; counts", 10, 0, 10) ); - AddHist( mHists["fwdMultEcalMatch"] = new TH1F("fwdMultEcalMatch", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); - AddHist( mHists["fwdMultHcalMatch"] = new TH1F("fwdMultHcalMatch", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); - AddHist( mHists["fwdMultEcalClusters"] = new TH1F("fwdMultEcalClusters", ";N_{Clu}^{ECAL}; counts", 100, 0, 100) ); - AddHist( mHists["fwdMultHcalClusters"] = new TH1F("fwdMultHcalClusters", ";N_{Clu}^{HCAL}; counts", 100, 0, 100) ); - AddHist( mHists["eta"] = new TH1F("eta", ";#eta; counts", 100, 0, 5) ); - AddHist( mHists["phi"] = new TH1F("phi", ";#phi; counts", 100, -3.1415926, 3.1415926) ); - AddHist( mHists["pt"] = new TH1F("pt", "; pT; counts", 500, 0, 10) ); - AddHist( mHists["charge"] = new TH1F("charge", "; charge; counts", 4, -2, 2) ); - AddHist( mHists["ecalMatchPerTrack"] = new TH1F("ecalMatchPerTrack", ";N_{match} / track; counts", 5, 0, 5) ); - AddHist( mHists["hcalMatchPerTrack"] = new TH1F("hcalMatchPerTrack", ";N_{match} / track; counts", 5, 0, 5) ); - AddHist( mHists["matchedEcalEnergy"] = new TH1F("matchedEcalEnergy", ";Energy; counts", 100, 0, 15) ); - AddHist( mHists["matchedHcalEnergy"] = new TH1F("matchedHcalEnergy", ";Energy; counts", 100, 0, 15) ); - AddHist( mHists["ecalEnergy"] = new TH1F("ecalEnergy", ";Energy; counts", 100, 0, 15) ); - AddHist( mHists["hcalEnergy"] = new TH1F("hcalEnergy", ";Energy; counts", 100, 0, 15) ); - AddHist( mHists["ecalXY"] = new TH2F( "ecalXY", ";ecalX;ecalY", 200, -200, 200, 200, -200, 200 ) ); - AddHist( mHists["hcalXY"] = new TH2F( "hcalXY", ";hcalX;hcalY", 200, 0, 50, 200, 0, 50 ) ); - AddHist( mHists["ecaldX"] = new TH1F( "ecaldX", ";dx (trk - ecal); counts", 400, -200, 200 ) ); - AddHist( mHists["matchedEcaldX"] = new TH1F( "matchedEcaldX", ";dx (trk - ecal); counts", 400, -200, 200 ) ); - AddHist( mHists["ecaldY"] = new TH1F( "ecaldY", ";dy (trk - ecal); counts", 400, -200, 200 ) ); - AddHist( mHists["matchedEcaldY"] = new TH1F( "matchedEcaldY", ";dy (trk - ecal); counts", 400, -200, 200 ) ); - AddHist( mHists["ecaldR"] = new TH1F( "ecaldR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); - AddHist( mHists["ecalMindR"] = new TH1F( "ecalMindR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); - AddHist( mHists["matchedEcaldR"] = new TH1F( "matchedEcaldR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); - AddHist( mHists["hcaldX"] = new TH1F( "hcaldX", ";dx (trk - hcal); counts", 400, -200, 200 ) ); - AddHist( mHists["hcaldXdNFit"] = new TH2F( "hcaldXdNFit", ";dx (trk - hcal); nFit", 400, -200, 200, 10, 0, 10 ) ); - AddHist( mHists["matchedHcaldX"] = new TH1F( "matchedHcaldX", ";dx (trk - hcal); counts", 400, -200, 200 ) ); - AddHist( mHists["hcaldY"] = new TH1F( "hcaldY", ";dy (trk - hcal); counts", 400, -200, 200 ) ); - AddHist( mHists["hcaldYdNFit"] = new TH2F( "hcaldYdNFit", ";dy (trk - hcal); nFit", 400, -200, 200, 10, 0, 10 ) ); - AddHist( mHists["matchedHcaldY"] = new TH1F( "matchedHcaldY", ";dy (trk - hcal); counts", 400, -200, 200 ) ); - AddHist( mHists["hcaldR"] = new TH1F( "hcaldR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); - AddHist( mHists["hcalMindR"] = new TH1F( "hcalMindR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); - AddHist( mHists["matchedHcaldR"] = new TH1F( "matchedHcaldR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); - AddHist( mHists["trkEcalX"] = new TH2F( "trkEcalX", ";trkX;ecalX", 300, -150, 150, 300, -150, 150 ) ); - AddHist( mHists["trkEcalY"] = new TH2F( "trkEcalY", ";trkY;ecalY", 300, -150, 150, 300, -150, 150 ) ); - AddHist( mHists["trkEcalMinX"] = new TH2F( "trkEcalMinX", ";trkX;ecalX", 300, -150, 150, 300, -150, 150 ) ); - AddHist( mHists["trkEcalMinY"] = new TH2F( "trkEcalMinY", ";trkY;ecalY", 300, -150, 150, 300, -150, 150 ) ); - AddHist( mHists["trkHcalX"] = new TH2F( "trkHcalX", ";trkX;hcalX", 300, -150, 150, 300, -150, 150 ) ); - AddHist( mHists["trkHcalY"] = new TH2F( "trkHcalY", ";trkY;hcalY", 300, -150, 150, 300, -150, 150 ) ); - AddHist( mHists["trkHcalMinX"] = new TH2F( "trkHcalMinX", ";trkX;hcalX", 300, -150, 150, 300, -150, 150 ) ); - AddHist( mHists["trkHcalMinY"] = new TH2F( "trkHcalMinY", ";trkY;hcalY", 300, -150, 150, 300, -150, 150 ) ); - -//=================================================================================================================================== - return kStOk; } - - - int StFwdQAMaker::Finish() { if ( mTreeFile && mTree ){ @@ -179,29 +127,8 @@ int StFwdQAMaker::Finish() { mTreeFile->Write(); LOG_DEBUG << "StFwdQA File written" << endm; } - - //beginning new - if ( mLocalOutputFile != "" ){ - auto prevDir = gDirectory; - - // output file name - TFile *fOutput = new TFile(mLocalOutputFile, "RECREATE"); - fOutput->cd(); - for (auto nh : mHists) { - nh.second->SetDirectory(gDirectory); - nh.second->Write(); - } - - // restore previous directory - gDirectory = prevDir; - - LOG_INFO << "Done writing StFwdQAMaker output to local file : " << mLocalOutputFile << endm; - }//end new - return kStOk; } - - int StFwdQAMaker::Make() { LOG_INFO << "FWD Report:" << endm; StEvent *mStEvent = static_cast(GetInputDS("StEvent")); @@ -209,50 +136,46 @@ int StFwdQAMaker::Make() { // report number of fwd tracks auto fwdTracks = mStEvent->fwdTrackCollection(); LOG_INFO << "Number of FwdTracks (StFwdTrackCollection): " << fwdTracks->tracks().size() << endm; - if ( mStEvent->fttCollection() ){ - LOG_INFO << "Number of Ftt Points (StEvent)" << mStEvent->fttCollection()->points().size() << endm; - } + LOG_INFO << "Number of Ftt Points (StEvent)" << mStEvent->fttCollection()->points().size() << endm; } LOG_INFO << "SETUP START" << endm; // setup the datasets / makers - - mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); if(mMuDstMaker) { mMuDst = mMuDstMaker->muDst(); mMuForwardTrackCollection = mMuDst->muFwdTrackCollection(); mMuFcsCollection = mMuDst->muFcsCollection(); - if (mMuDst->event()) - mTreeData.header.run = mMuDst->event()->runNumber(); if (mMuForwardTrackCollection){ LOG_DEBUG << "Number of StMuFwdTracks: " << mMuForwardTrackCollection->numberOfFwdTracks() << endm; } - else{ - LOG_DEBUG << "No muFwdTrackCollection " << endm; - } } else { LOG_DEBUG << "No StMuDstMaker found: " << mMuDstMaker << endm; } - mFcsDb = static_cast(GetDataSet("fcsDb")); + mFwdTrackMaker = (StFwdTrackMaker*) GetMaker( "fwdTrack" ); if (!mFwdTrackMaker) { LOG_WARN << "No StFwdTrackMaker found, skipping StFwdQAMaker" << endm; // return kStOk; } - + mTreeData.header.run = mMuDst->event()->runNumber(); LOG_DEBUG << "SETUP COMPLETE" << endm; - ProcessFwdTracks(); - ProcessFwdMuTracks(); + auto muFstCollection = mMuDst->muFstCollection(); + if ( muFstCollection ){ + LOG_DEBUG << "MuDst has #fst hits: " << muFstCollection->numberOfHits() << endm; + for ( size_t i = 0; i < muFstCollection->numberOfHits(); i++ ){ + StMuFstHit * h = muFstCollection->getHit(i); + mTreeData.fstPoints.add( h ); + } + } FillMcTracks(); - FillTracks(); //maybe not running - FillFstPoints(); //no fst + FillTracks(); + FillFstPoints(); FillFttClusters(); FillFcsStMuDst(); mTree->Fill(); - return kStOk; } void StFwdQAMaker::Clear(const Option_t *opts) { @@ -267,10 +190,36 @@ void StFwdQAMaker::FillFstPoints(){ return; } + // size_t numFwdHitsPrior = mFwdHitsFst.size(); LOG_INFO << "Loading " << fst->numberOfHits() << " StMuFstHits" << endm; + // TMatrixDSym hitCov3(3); for ( unsigned int index = 0; index < fst->numberOfHits(); index++){ StMuFstHit * muFstHit = fst->getHit( index ); mTreeData.fstPoints.add( muFstHit ); + + + // float vR = muFstHit->localPosition(0); + // float vPhi = muFstHit->localPosition(1); + // float vZ = muFstHit->localPosition(2); + + // const float dz0 = fabs( vZ - mFstZFromGeom[0] ); + // const float dz1 = fabs( vZ - mFstZFromGeom[1] ); + // const float dz2 = fabs( vZ - mFstZFromGeom[2] ); + // static const float fstThickness = 2.0; // thickness in cm between inner and outer on sigle plane + + // // assign disk according to which z value the hit has, within the z-plane thickness + // int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); + + // float x0 = vR * cos( vPhi ); + // float y0 = vR * sin( vPhi ); + // hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); + + // LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; + // mFstHits.push_back( TVector3( x0, y0, vZ) ); + + // // we use d+4 so that both FTT and FST start at 4 + // mFwdHitsFst.push_back(FwdHit(count++, x0, y0, vZ, d+4, 0, hitCov3, nullptr)); + // count++; } // index } @@ -295,8 +244,6 @@ void StFwdQAMaker::FillTracks() { break; } } - } else { - LOG_WARN << "No StMuFwdTrackCollection found" << endm; } LOG_DEBUG << "TRACKS COMPLETE" << endm; } @@ -326,7 +273,7 @@ void StFwdQAMaker::FillFcsStMuDst( ) { } else if ( clu->detectorId() == kFcsHcalNorthDetId || clu->detectorId() == kFcsHcalSouthDetId ){ LOG_INFO << "Adding HCAL Cluster to FwdTree" << endm; mTreeData.hcal.add( cluSTAR ); - } + } delete cluSTAR; } @@ -383,325 +330,4 @@ void StFwdQAMaker::FillFttClusters(){ mTreeData.fttPoints.add( c ); } } - else{ - LOG_INFO << "no muFttCollection " << endm; - } -} - -//==================================================adding new function - -void StFwdQAMaker::ProcessFwdTracks( ){ - // This is an example of how to process fwd track collection - LOG_DEBUG << "StFwdAnalysisMaker::ProcessFwdTracks" << endm; - StEvent *stEvent = static_cast(GetInputDS("StEvent")); - if (!stEvent) - return; - - if (stEvent){ - StFttCollection *fttCol = stEvent->fttCollection(); - if (fttCol){ - LOG_DEBUG << "The Ftt Collection has " << fttCol->numberOfPoints() << " points" << endm; - } - } - StFwdTrackCollection * ftc = stEvent->fwdTrackCollection(); - if (!ftc) { - LOG_DEBUG << "Forward Track Collection is not present" << endm; - return; - } - - LOG_DEBUG << "Checking FcsCollection" << endm; - StFcsCollection *fcs = stEvent->fcsCollection(); - if (!fcs) return; - - StFcsDb *mFcsDb = static_cast(GetDataSet("fcsDb")); - - size_t fwdMultEcalMatch = 0; - size_t fwdMultHcalMatch = 0; - size_t fwdMultFST = 0; - - LOG_INFO << "FwdTrackCollection has: " << ftc->tracks().size() << " tracks" << endm; - - getHist( "fwdMultAll" )->Fill( ftc->tracks().size() ); - - // Cluster info (independen t of tracks) - size_t fwdMultEcalClusters = 0; - size_t fwdMultHcalClusters = 0; - for ( int iDet = 0; iDet < 4; iDet++ ){ - for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ - StFcsCluster * clu = fcs->clusters(iDet)[i]; - - if ( iDet < 2 ){ - fwdMultEcalClusters++; - getHist( "ecalEnergy" )->Fill( clu->energy() ); - } else if ( iDet < 4 ){ - fwdMultHcalClusters++; - getHist( "hcalEnergy" )->Fill( clu->energy() ); - } - } - } - - getHist( "fwdMultEcalClusters" )->Fill( fwdMultEcalClusters ); - getHist( "fwdMultHcalClusters" )->Fill( fwdMultHcalClusters ); - - - size_t nGood = 0; - size_t nFailed = 0; - for ( auto fwdTrack : ftc->tracks() ){ - if ( !fwdTrack->didFitConvergeFully() ) { - nFailed++; - continue; - } - nGood++; - LOG_DEBUG << TString::Format("StFwdTrack[ nProjections=%lu, nFTTSeeds=%lu, nFSTSeeds=%lu, mPt=%f ]", fwdTrack->mProjections.size(), fwdTrack->mFTTPoints.size(), fwdTrack->mFSTPoints.size(), fwdTrack->momentum().perp()) << endm; - LOG_DEBUG << "track fit momentum " << TString::Format( "(pt=%f, eta=%f, phi=%f)", fwdTrack->momentum().perp(), fwdTrack->momentum().pseudoRapidity(), fwdTrack->momentum().phi() ) << endm; - LOG_DEBUG << "StFwdTrack has " << fwdTrack->ecalClusters().size() << " ecal matches" << endm; - LOG_DEBUG << "StFwdTrack has " << fwdTrack->hcalClusters().size() << " hcal matches" << endm; - - getHist("ecalMatchPerTrack")->Fill( fwdTrack->ecalClusters().size() ); - getHist("hcalMatchPerTrack")->Fill( fwdTrack->hcalClusters().size() ); - - getHist( "nHitsFit" )->Fill( fwdTrack->numberOfFitPoints() ); - - if (fwdTrack->mFSTPoints.size() > 0){ - fwdMultFST ++; - } - - getHist("eta")->Fill( fwdTrack->momentum().pseudoRapidity() ); - getHist("phi")->Fill( fwdTrack->momentum().phi() ); - getHist("pt")->Fill( fwdTrack->momentum().perp() ); - - getHist("charge")->Fill( fwdTrack->charge() ); - - // ecal proj - int detId = kFcsWcalId; - TVector3 ecalXYZ; - TVector3 ecapP; - - StFwdTrackProjection ecalProj = fwdTrack->getProjectionFor( detId, 0 ); - StFwdTrackProjection hcalProj = fwdTrack->getProjectionFor( kFcsHcalId, 0 ); - LOG_DEBUG << "EcalProj z= " << ecalProj.mXYZ.z() << endm; - LOG_DEBUG << "HcalProj z= " << hcalProj.mXYZ.z() << endm; - LOG_DEBUG << "EcalProj Mom" << TString::Format( "(pt=%f, eta=%f, phi=%f)", ecalProj.mMom.perp(), ecalProj.mMom.pseudoRapidity(), ecalProj.mMom.phi() ) << endm; - - for ( size_t iEcal = 0; iEcal < fwdTrack->ecalClusters().size(); iEcal++ ){ - StFcsCluster *clu = fwdTrack->ecalClusters()[iEcal]; - LOG_DEBUG << "Ecal clu detId = " << clu->detectorId() << endm; - getHist("matchedEcalEnergy")->Fill( clu->energy() ); - - StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); - float dx = ecalProj.mXYZ.x() - xyz.x(); - float dy = ecalProj.mXYZ.y() - xyz.y(); - float dr = sqrt(dx*dx + dy*dy); - getHist("matchedEcaldX")->Fill( dx ); - getHist("matchedEcaldY")->Fill( dy ); - getHist("matchedEcaldR")->Fill( dr ); - } - - if (ecalProj.mXYZ.z() > 500){ - double mindR = 999; - StFcsCluster * cclu = nullptr; // closet cluster - for ( int iDet = 0; iDet < 2; iDet++ ){ - for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ - StFcsCluster * clu = fcs->clusters(iDet)[i]; - - StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); - getHist("ecalXY")->Fill( xyz.x(), xyz.y() ); - - float dx = ecalProj.mXYZ.x() - xyz.x(); - float dy = ecalProj.mXYZ.y() - xyz.y(); - float dr = sqrt(dx*dx + dy*dy); - - if ( fabs(dy) < 25 ) - getHist( "ecaldX" )->Fill( dx ); - if ( fabs(dx) < 25 ) - getHist( "ecaldY" )->Fill( dy ); - getHist( "ecaldR" )->Fill( dr ); - if ( dr < mindR ){ - mindR = dr; - cclu = clu; - } - - getHist( "trkEcalX" ) -> Fill( ecalProj.mXYZ.x(), xyz.x() ); - getHist( "trkEcalY" ) -> Fill( ecalProj.mXYZ.y(), xyz.y() ); - - } - } - getHist( "ecalMindR" )->Fill( mindR ); - if (cclu){ - StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(cclu->detectorId(), cclu->x(), cclu->y()); - getHist( "trkEcalMinX" ) -> Fill( ecalProj.mXYZ.x(), xyz.x() ); - getHist( "trkEcalMinY" ) -> Fill( ecalProj.mXYZ.y(), xyz.y() ); - } - } - - if (hcalProj.mXYZ.z() > 500){ - - double mindR = 999; - StFcsCluster * cclu = nullptr; - for ( int iDet = 2; iDet < 4; iDet++ ){ - for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ - StFcsCluster * clu = fcs->clusters(iDet)[i]; - if (!clu) continue; - StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); - getHist("hcalXY")->Fill( xyz.x(), xyz.y() ); - - float dx = hcalProj.mXYZ.x() - xyz.x(); - float dy = hcalProj.mXYZ.y() - xyz.y(); - float dr = sqrt(dx*dx + dy*dy); - - if ( fabs(dy) < 25 ){ - getHist( "hcaldX" )->Fill( dx ); - getHist( "hcaldXdNFit" )->Fill( dx, fwdTrack->numberOfFitPoints() ); - - } - if ( fabs(dx) < 25 ){ - getHist( "hcaldY" )->Fill( dy ); - getHist( "hcaldYdNFit" )->Fill( dy, fwdTrack->numberOfFitPoints() ); - } - getHist( "hcaldR" )->Fill( dr ); - - if ( dr < mindR ){ - mindR = dr; - cclu = clu; - } - - getHist( "trkHcalX" ) -> Fill( hcalProj.mXYZ.x(), xyz.x() ); - getHist( "trkHcalY" ) -> Fill( hcalProj.mXYZ.y(), xyz.y() ); - } - } - getHist( "hcalMindR" )->Fill( mindR ); - if (cclu){ - StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(cclu->detectorId(), cclu->x(), cclu->y()); - getHist( "trkHcalMinX" ) -> Fill( hcalProj.mXYZ.x(), xyz.x() ); - getHist( "trkHcalMinY" ) -> Fill( hcalProj.mXYZ.y(), xyz.y() ); - } - } - - if (fwdTrack->ecalClusters().size() > 0) - fwdMultEcalMatch++; - if (fwdTrack->hcalClusters().size() > 0) - fwdMultHcalMatch++; - - } // Loop ftc->tracks() - - getHist( "fwdMultGood" )->Fill( nGood ); - getHist( "fwdMultFailed" )->Fill( nFailed ); - getHist("fwdMultFST")->Fill( fwdMultFST ); - getHist("fwdMultHcalMatch")->Fill( fwdMultHcalMatch ); - getHist("fwdMultEcalMatch")->Fill( fwdMultEcalMatch ); - - LOG_INFO << "Found " << nFailed << " failed track fits out of " << ftc->tracks().size() << endm; -} // ProcessFwdTracks -//========================================================end of added function - - - -void StFwdQAMaker::ProcessFwdMuTracks( ){ - // This is an example of how to process fwd track collection - LOG_DEBUG << "StFwdAnalysisMaker::ProcessFwdMuTracks" << endm; - StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); - if(!mMuDstMaker) { - LOG_WARN << " No MuDstMaker ... bye-bye" << endm; - return; - } - StMuDst *mMuDst = mMuDstMaker->muDst(); - if(!mMuDst) { - LOG_WARN << " No MuDst ... bye-bye" << endm; - return; - } - StMuFwdTrackCollection * ftc = mMuDst->muFwdTrackCollection(); - if (!ftc) return; - - StMuFcsCollection *fcs = mMuDst->muFcsCollection(); - if (!fcs) return; - - LOG_INFO << "Number of StMuFwdTracks: " << ftc->numberOfFwdTracks() << endl; - - StFcsDb *mFcsDb = static_cast(GetDataSet("fcsDb")); - - size_t fwdMultFST = 0; - size_t fwdMultEcalMatch = 0; - size_t fwdMultHcalMatch = 0; - - for ( size_t iTrack = 0; iTrack < ftc->numberOfFwdTracks(); iTrack++ ){ - StMuFwdTrack * muFwdTrack = ftc->getFwdTrack( iTrack ); - // LOG_DEBUG << TString::Format("StMuFwdTrack[ nProjections=%lu, nFTTSeeds=%lu, nFSTSeeds=%lu, mPt=%f ]", muFwdTrack->mProjections.size(), muFwdTrack->mFTTPoints.size(), muFwdTrack->mFSTPoints.size(), muFwdTrack->momentum().Pt()) << endm; - - LOG_DEBUG << "StMuFwdTrack has " << muFwdTrack->mEcalClusters.GetEntries() << " Ecal matched" << endm; - LOG_DEBUG << "StMuFwdTrack has " << muFwdTrack->mHcalClusters.GetEntries() << " Hcal matched" << endm; - - getHist("eta")->Fill( muFwdTrack->momentum().Eta() ); - getHist("phi")->Fill( muFwdTrack->momentum().Phi() ); - - if (muFwdTrack->mFSTPoints.size() > 0){ - fwdMultFST ++; - } - - if (muFwdTrack->mEcalClusters.GetEntries() > 0) - fwdMultEcalMatch++; - if (muFwdTrack->mHcalClusters.GetEntries() > 0) - fwdMultHcalMatch++; - - - // ecal proj - int detId = kFcsWcalId; - TVector3 ecalXYZ; - TVector3 ecapP; - - StMuFwdTrackProjection ecalProj; - bool foundEcalProj = muFwdTrack->getProjectionFor( detId, ecalProj, 0 ); - - if (foundEcalProj){ - for( size_t i = 0; i < fcs->numberOfClusters(); i++){ - StMuFcsCluster * clu = fcs->getCluster(i); - - if ( clu->detectorId() > 1 ) continue; - - if ( clu->energy() < 1 ) continue; - StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); - - float dx = ecalProj.mXYZ.X() - xyz.x(); - float dy = ecalProj.mXYZ.Y() - xyz.y(); - float dr = sqrt(dx*dx + dy*dy); - - getHist( "ecaldX" )->Fill( dx ); - getHist( "ecaldY" )->Fill( dy ); - getHist( "ecaldR" )->Fill( dr ); - - getHist( "trkEcalX" ) -> Fill( ecalProj.mXYZ.X(), xyz.x() ); - - } // i - } // foundEcalProj - - - for ( int i = 0; i < muFwdTrack->mEcalClusters.GetEntries(); i++ ){ - auto c = (StMuFcsCluster*) muFwdTrack->mEcalClusters.At(i); - if (!c) continue; - getHist("ecalEnergy")->Fill( c->energy() ); - - LOG_DEBUG << "eCal Cluster detId = " << c->detectorId() << endm; - StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(c->detectorId(), c->x(), c->y()); - getHist("ecalXY")->Fill( xyz.x(), xyz.y() ); - - if (foundEcalProj){ - getHist("matchedEcaldX")->Fill( ecalProj.mXYZ.X() - xyz.x() ); - } - } // i - - getHist("ecalMatchPerTrack")->Fill( muFwdTrack->mEcalClusters.GetEntries() ); - getHist("hcalMatchPerTrack")->Fill( muFwdTrack->mHcalClusters.GetEntries() ); - - for ( int i = 0; i < muFwdTrack->mHcalClusters.GetEntries(); i++ ){ - auto c = (StMuFcsCluster*) muFwdTrack->mHcalClusters.At(i); - if (!c) continue; - getHist("hcalEnergy")->Fill( c->energy() ); - - getHist("hcalXY")->Fill( c->x(), c->y() ); - } // i - } // iTrack - - getHist("fwdMult")->Fill( ftc->numberOfFwdTracks() ); - getHist("fwdMultFST")->Fill( fwdMultFST ); - getHist("fwdMultHcalMatch")->Fill( fwdMultHcalMatch ); - getHist("fwdMultEcalMatch")->Fill( fwdMultEcalMatch ); } diff --git a/StRoot/StFwdTrackMaker/StFwdQAMaker.h b/StRoot/StFwdTrackMaker/StFwdQAMaker.h index b6f32db3724..bc60f98d5b4 100644 --- a/StRoot/StFwdTrackMaker/StFwdQAMaker.h +++ b/StRoot/StFwdTrackMaker/StFwdQAMaker.h @@ -15,8 +15,6 @@ #include "StEvent/StEnumerations.h" #include "StThreeVectorD.hh" -#include - class StMuFwdTrack; class StMuFwdTrackProjection; class ForwardTracker; @@ -200,13 +198,6 @@ class StFwdQAMaker : public StMaker { void FillTracks(); void FillMcTracks(); - void ProcessFwdTracks(); - void ProcessFwdMuTracks(); - - void setMuDstInput() { mAnalyzeMuDst = true; } - void setLocalOutputFile( TString f ) { mLocalOutputFile = f; } - void setTreeFilename( TString f ) {mTreeFilename = f;} - protected: TFile *mTreeFile = nullptr; TTree *mTree = nullptr; @@ -220,32 +211,6 @@ class StFwdQAMaker : public StMaker { StFwdTrackMaker *mFwdTrackMaker = nullptr; StFcsDb *mFcsDb = nullptr; - -//========================================================= new stuff - std::map mHists; - - /** - * @brief Get the Hist object from the map - * - Additional check and safety for missing histograms - * @param n Histogram name - * @return TH1* histogram if found, otherwise a 'nil' histogram with one bin - */ - TH1* getHist( TString n ){ - if (mHists.count(n)) - return mHists[n]; - LOG_ERROR << "Attempting to access non-existing histogram" << endm; - return new TH1F( "NULL", "NULL", 1, 0, 1 ); // returning nullptr can lead to seg fault, this fails softly - } - - /** - * @brief Control whether the analysis uses StEvent (default) or MuDst as input - * - */ - bool mAnalyzeMuDst = false; - TString mLocalOutputFile; - TString mTreeFilename; -//====================================================== end new stuff - }; diff --git a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx index 4e1d6d39fa4..a2881f3f660 100644 --- a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx +++ b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx @@ -7,10 +7,11 @@ #include "KiTrack/IHit.h" #include "GenFit/Track.h" +#include "GenFit/GFRaveVertexFactory.h" #include "TMath.h" -#include +#include #include #include #include @@ -25,8 +26,6 @@ #include "StEvent/StRnDHit.h" #include "StEvent/StRnDHitCollection.h" #include "StEvent/StTrack.h" -#include "StEvent/StBTofCollection.h" -#include "StEvent/StBTofHeader.h" #include "StEvent/StTrackGeometry.h" #include "StEvent/StTrackNode.h" #include "StEvent/StPrimaryVertex.h" @@ -45,9 +44,6 @@ #include "StEventUtilities/StEventHelper.h" -#include "StMcEvent/StMcEvent.hh" -#include "StMcEvent/StMcVertex.hh" - #include "tables/St_g2t_fts_hit_Table.h" #include "tables/St_g2t_track_Table.h" #include "tables/St_g2t_vertex_Table.h" @@ -72,16 +68,15 @@ #include "StEvent/StFwdTrack.h" #include "GenFit/AbsMeasurement.h" -#include "StMuDSTMaker/COMMON/StMuDstMaker.h" -#include "StMuDSTMaker/COMMON/StMuDst.h" -#include "StMuDSTMaker/COMMON/StMuFstCollection.h" -#include "StMuDSTMaker/COMMON/StMuFstHit.h" -#include "StMuDSTMaker/COMMON/StMuPrimaryVertex.h" - -#include "sys/types.h" -#include "sys/sysinfo.h" FwdSystem* FwdSystem::sInstance = nullptr; +TMVA::Reader * BDTCrit2::reader = nullptr; +float BDTCrit2::Crit2_RZRatio = -999; +float BDTCrit2::Crit2_DeltaRho = -999; +float BDTCrit2::Crit2_DeltaPhi = -999; +float BDTCrit2::Crit2_StraightTrackRatio = -999; + + //_______________________________________________________________________________________ class GenfitUtils{ @@ -89,6 +84,8 @@ class GenfitUtils{ // For now, accept anything we are passed, no matter what it is or how bad it is template static bool accept( T ) { return true; } + + }; // GenfitUtils // Basic sanity cuts on genfit tracks @@ -115,10 +112,10 @@ template<> bool GenfitUtils::accept( genfit::Track *track ) } } - // Following line fails with an exception, because some tracks lack + // Following line fails with an exception, because some tracks lack // forward update, or prediction in fitter info at the first point // - // genfit::KalmanFitterInfo::getFittedState(bool) const of + // genfit::KalmanFitterInfo::getFittedState(bool) const of // GenFit/fitters/src/KalmanFitterInfo.cc:250 // Fitted state at the first point @@ -133,7 +130,7 @@ template<> bool GenfitUtils::accept( genfit::Track *track ) for ( ipoint = 0; ipoint < track->getNumPoints(); ipoint++ ) { first = track->getPointWithFitterInfo( ipoint ); if ( first ) break; - } + } // No points on the track have fit information if ( !first ) { @@ -161,7 +158,7 @@ class SiRasterizer { void setup(FwdTrackerConfig &_cfg) { cfg = _cfg; mRasterR = cfg.get("SiRasterizer:r", 3.0); - mRasterPhi = cfg.get("SiRasterizer:phi", 0.004); + mRasterPhi = cfg.get("SiRasterizer:phi", 0.1); } bool active() { @@ -194,8 +191,13 @@ class ForwardTracker : public ForwardTrackMaker { // Create the forward system... FwdSystem::sInstance = new FwdSystem(); + // make our quality plotter + mQualityPlotter = new QualityPlotter(mConfig); + mQualityPlotter->makeHistograms(mConfig.get("TrackFinder:nIterations", 1)); + // initialize the track fitter mTrackFitter = new TrackFitter(mConfig, geoCache); + mTrackFitter->setGenerateHistograms(genHistograms); mTrackFitter->setup(); ForwardTrackMaker::initialize( geoCache, genHistograms ); @@ -203,10 +205,19 @@ class ForwardTracker : public ForwardTrackMaker { void finish() { + if ( mGenHistograms ){ + mQualityPlotter->finish(); + writeEventHistograms(); + } + if (FwdSystem::sInstance){ delete FwdSystem::sInstance; FwdSystem::sInstance = 0; } + if (mQualityPlotter){ + delete mQualityPlotter; + mQualityPlotter = 0; + } if (mTrackFitter){ delete mTrackFitter; mTrackFitter= 0; @@ -215,8 +226,8 @@ class ForwardTracker : public ForwardTrackMaker { }; //________________________________________________________________________ -StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mForwardTracker(nullptr), mForwardData(nullptr), mGeoCache(""){ - SetAttr("useFtt",1); // Default Ftt on +StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mGenHistograms(false), mGenTree(false), mForwardTracker(nullptr), mForwardData(nullptr){ + SetAttr("useFtt",1); // Default Ftt on SetAttr("useFst",1); // Default Fst on SetAttr("useFcs",1); // Default Fcs on SetAttr("config", "config.xml"); // Default configuration file (user may override before Init()) @@ -224,12 +235,39 @@ StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mForwardTracker(nullpt }; int StFwdTrackMaker::Finish() { + + auto prevDir = gDirectory; + if ( mGenHistograms ) { + + // output file name + string name = mFwdConfig.get("Output:url", "fwdTrackerOutput.root"); + LOG_INFO << "Saving StFwdTrackMaker Histograms to ROOT file: " << name << endm; + TFile *fOutput = new TFile(name.c_str(), "RECREATE"); + fOutput->cd(); + + fOutput->mkdir("StFwdTrackMaker"); + fOutput->cd("StFwdTrackMaker"); + for (auto nh : mHistograms) { + nh.second->SetDirectory(gDirectory); + nh.second->Write(); + } + fOutput->cd(""); + } + mForwardTracker->finish(); + + prevDir->cd(); + + if (mGenTree) { + mTreeFile->cd(); + mTree->Write(); + mTreeFile->Write(); + } return kStOk; } void StFwdTrackMaker::LoadConfiguration() { - if (mConfigFile.length() < 5){ + if (mConfigFile.length() < 5){ LOG_INFO << "Forward Tracker is using default config for "; if ( defaultConfig == defaultConfigData ){ LOG_INFO << " DATA" << endm; @@ -246,46 +284,226 @@ void StFwdTrackMaker::LoadConfiguration() { //________________________________________________________________________ int StFwdTrackMaker::Init() { + if ( !configLoaded ){ LoadConfiguration(); } - if ( mGeoCache == "" ){ - /// Instantiate and cache the geometry - GetDataBase("VmcGeometry"); + if (mGenTree) { + mTreeFile = new TFile("fwdtree.root", "RECREATE"); + mTree = new TTree("fwd", "fwd tracking tree"); + mTree->Branch("fttN", &mTreeData. fttN, "fttN/I"); + mTree->Branch("fttX", &mTreeData. fttX ); + mTree->Branch("fttY", &mTreeData. fttY ); + mTree->Branch("fttZ", &mTreeData. fttZ ); + + mTree->Branch("fttTrackId", &mTreeData. fttTrackId ); + mTree->Branch("fttVolumeId", &mTreeData. fttVolumeId ); + mTree->Branch("fttPt", &mTreeData. fttPt ); + mTree->Branch("fttVertexId", &mTreeData. fttVertexId ); + + mTree->Branch("fstN", &mTreeData. fstN, "fstN/I"); + mTree->Branch("fstX", &mTreeData. fstX ); + mTree->Branch("fstY", &mTreeData. fstY ); + mTree->Branch("fstZ", &mTreeData. fstZ ); + mTree->Branch("fstTrackId", &mTreeData. fstTrackId ); + + mTree->Branch("fcsN", &mTreeData. fcsN, "fcsN/I"); + mTree->Branch("fcsX", &mTreeData. fcsX ); + mTree->Branch("fcsY", &mTreeData. fcsY ); + mTree->Branch("fcsZ", &mTreeData. fcsZ ); + mTree->Branch("fcsDet", &mTreeData. fcsDet ); + + // mc tracks + mTree->Branch("mcN", &mTreeData. mcN, "mcN/I"); + mTree->Branch("mcPt", &mTreeData. mcPt ); + mTree->Branch("mcEta", &mTreeData. mcEta ); + mTree->Branch("mcPhi", &mTreeData. mcPhi ); + mTree->Branch("mcCharge", &mTreeData. mcCharge ); + mTree->Branch("mcVertexId", &mTreeData. mcVertexId ); + + // mcverts + mTree->Branch("vmcN", &mTreeData. vmcN, "vmcN/I"); + mTree->Branch("vmcX", &mTreeData. vmcX ); + mTree->Branch("vmcY", &mTreeData. vmcY ); + mTree->Branch("vmcZ", &mTreeData. vmcZ ); + + // rcverts + mTree->Branch("vrcN", &mTreeData. vrcN, "vrcN/I"); + mTree->Branch("vrcX", &mTreeData. vrcX ); + mTree->Branch("vrcY", &mTreeData. vrcY ); + mTree->Branch("vrcZ", &mTreeData. vrcZ ); + + // rc tracks + mTree->Branch("rcN", &mTreeData. rcN, "rcN/I"); + mTree->Branch("rcPt", &mTreeData. rcPt ); + mTree->Branch("rcEta", &mTreeData. rcEta ); + mTree->Branch("rcPhi", &mTreeData. rcPhi ); + mTree->Branch("rcCharge", &mTreeData. rcCharge ); + mTree->Branch("rcTrackId", &mTreeData. rcTrackId ); + mTree->Branch("rcNumFST", &mTreeData. rcNumFST ); + mTree->Branch("rcNumFTT", &mTreeData. rcNumFTT ); + mTree->Branch("rcNumPV", &mTreeData. rcNumPV ); + mTree->Branch("rcQuality", &mTreeData. rcQuality ); + + mTree->Branch("thdN", &mTreeData. thdN, "thdN/I"); + mTree->Branch("thdX", &mTreeData. thdX ); + mTree->Branch("thdY", &mTreeData. thdY ); + mTree->Branch("thaX", &mTreeData. thaX ); + mTree->Branch("thaY", &mTreeData. thaY ); + mTree->Branch("thaZ", &mTreeData. thaZ ); + + // track projections + mTree->Branch("tprojN", &mTreeData. tprojN, "tprojN/I"); + mTree->Branch("tprojIdD", &mTreeData. tprojIdD); + mTree->Branch("tprojIdT", &mTreeData. tprojIdT); + mTree->Branch("tprojX", &mTreeData. tprojX); + mTree->Branch("tprojY", &mTreeData. tprojY); + mTree->Branch("tprojZ", &mTreeData. tprojZ); + mTree->Branch("tprojPx", &mTreeData. tprojPx); + mTree->Branch("tprojPy", &mTreeData. tprojPy); + mTree->Branch("tprojPz", &mTreeData. tprojPz); + + std::string path = "TrackFinder.Iteration[0].SegmentBuilder"; + std::vector paths = mFwdConfig.childrenOf(path); + + if (mTreeData.saveCrit){ + for (string p : paths) { + string name = mFwdConfig.get(p + ":name", ""); + mTreeData.Crits[name]; // create the entry + mTree->Branch(name.c_str(), &mTreeData.Crits[name]); + mTree->Branch((name + "_trackIds").c_str(), &mTreeData.CritTrackIds[name]); + + if ( name == "Crit2_RZRatio" ){ + string n = name + "_x1"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + + n = name + "_y1"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + + n = name + "_z1"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + + n = name + "_x2"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + + n = name + "_y2"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + + n = name + "_z2"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + + n = name + "_h1"; + mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); + n = name + "_h2"; + mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); + n = name + "_h3"; + mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); + } + + if ( name == "Crit2_BDT" ){ + string n = name + "_DeltaPhi"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + n = name + "_DeltaRho"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + n = name + "_RZRatio"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + n = name + "_StraightTrackRatio"; + mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); + } + } - mGeoCache = GetChainOpt()->GetFileOut(); - if ( mGeoCache=="" ) - mGeoCache = GetChainOpt()->GetFileIn(); + // Three hit criteria + path = "TrackFinder.Iteration[0].ThreeHitSegments"; + paths = mFwdConfig.childrenOf(path); - // Strip out @ symbol - mGeoCache = mGeoCache.ReplaceAll("@",""); - // Strip off the last extention in the mGeoCache - mGeoCache = mGeoCache( 0, mGeoCache.Last('.') ); - // Append geom.root to the extentionless mGeoCache - mGeoCache+=".geom.root"; - } - // create an SiRasterizer in case we need it + for (string p : paths) { + string name = mFwdConfig.get(p + ":name", ""); + mTreeData.Crits[name]; // create the entry + mTree->Branch(name.c_str(), &mTreeData.Crits[name]); + mTree->Branch((name + "_trackIds").c_str(), &mTreeData.CritTrackIds[name]); + } + } + + mTree->SetAutoFlush(0); + } // gen tree + + + /// Instantiate and cache the geometry + GetDataBase("VmcGeometry"); + + + + TString geoCache = GetChainOpt()->GetFileOut(); + if ( geoCache=="" ) + geoCache = GetChainOpt()->GetFileIn(); + + // Strip out @ symbol + geoCache = geoCache.ReplaceAll("@",""); + // Strip off the last extention in the geoCache + geoCache = geoCache( 0, geoCache.Last('.') ); + // Append geom.root to the extentionless geoCache + geoCache+=".geom.root"; + + // create an SiRasterizer in case we need it mSiRasterizer = std::shared_ptr( new SiRasterizer(mFwdConfig)); mForwardTracker = std::shared_ptr(new ForwardTracker( )); mForwardTracker->setConfig(mFwdConfig); - // in production we disable crit saving. - mForwardTracker->setSaveCriteriaValues(false); + // only save criteria values if we are generating a tree. + mForwardTracker->setSaveCriteriaValues(mGenTree); mForwardData = std::shared_ptr(new FwdDataSource()); mForwardTracker->setData(mForwardData); - mForwardTracker->initialize( mGeoCache, false ); + mForwardTracker->initialize( geoCache, mGenHistograms ); - // geometry should be available from here (mForwardTracker will initialize cache if needed) - if (gGeoManager) { - FwdGeomUtils fwdGeoUtils( gGeoManager ); - // get the z-locations from geometry model and fallback to the defaults - auto fstZ = fwdGeoUtils.fstZ( {151.750000, 165.248001, 178.781006} ); - mFstZFromGeom.assign( fstZ.begin(), fstZ.end() ); - auto fttZ = fwdGeoUtils.fttZ( {280.904999, 303.704987, 326.605011, 349.404999} ); - mFttZFromGeom.assign( fttZ.begin(), fttZ.end() ); - } + if ( mGenHistograms ){ + mHistograms["fwdVertexZ"] = new TH1D("fwdVertexZ", "FWD Vertex (RAVE);z", 1000, -50, 50); + mHistograms["fwdVertexXY"] = new TH2D("fwdVertexXY", "FWD Vertex (RAVE);x;y", 100, -1, 1, 100, -1, 1); + mHistograms["fwdVertexDeltaZ"] = new TH2D("fwdVertexDeltaZ", "FWD Vertex - MC Vertex;#Delta z", 100, -1, 1, 100, -1, 1); + + mHistograms["McEventEta"] = new TH1D("McEventEta", ";MC Track Eta", 1000, -5, 5); + mHistograms["McEventPt"] = new TH1D("McEventPt", ";MC Track Pt (GeV/c)", 1000, 0, 10); + mHistograms["McEventPhi"] = new TH1D("McEventPhi", ";MC Track Phi", 1000, 0, 6.2831852); + + // these are tracks within 2.5 < eta < 4.0 + mHistograms["McEventFwdEta"] = new TH1D("McEventFwdEta", ";MC Track Eta", 1000, -5, 5); + mHistograms["McEventFwdPt"] = new TH1D("McEventFwdPt", ";MC Track Pt (GeV/c)", 1000, 0, 10); + mHistograms["McEventFwdPhi"] = new TH1D("McEventFwdPhi", ";MC Track Phi", 1000, 0, 6.2831852); + + // create mHistograms + mHistograms["nMcTracks"] = new TH1I("nMcTracks", ";# MC Tracks/Event", 1000, 0, 1000); + mHistograms["nMcTracksFwd"] = new TH1I("nMcTracksFwd", ";# MC Tracks/Event", 1000, 0, 1000); + mHistograms["nMcTracksFwdNoThreshold"] = new TH1I("nMcTracksFwdNoThreshold", ";# MC Tracks/Event", 1000, 0, 1000); + + mHistograms["nHitsSTGC"] = new TH1I("nHitsSTGC", ";# STGC Hits/Event", 1000, 0, 1000); + mHistograms["nHitsFSI"] = new TH1I("nHitsFSI", ";# FSIT Hits/Event", 1000, 0, 1000); + + mHistograms["stgc_volume_id"] = new TH1I("stgc_volume_id", ";stgc_volume_id", 50, 0, 50); + mHistograms["fsi_volume_id"] = new TH1I("fsi_volume_id", ";fsi_volume_id", 50, 0, 50); + + mHistograms["fsiHitDeltaR"] = new TH1F("fsiHitDeltaR", "FSI; delta r (cm); ", 500, -5, 5); + mHistograms["fsiHitDeltaPhi"] = new TH1F("fsiHitDeltaPhi", "FSI; delta phi; ", 500, -5, 5); + + // there are 4 stgc stations + for (int i = 0; i < 4; i++) { + mHistograms[TString::Format("stgc%dHitMap", i).Data()] = new TH2F(TString::Format("stgc%dHitMap", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); + + mHistograms[TString::Format("stgc%dHitMapPrim", i).Data()] = new TH2F(TString::Format("stgc%dHitMapPrim", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); + mHistograms[TString::Format("stgc%dHitMapSec", i).Data()] = new TH2F(TString::Format("stgc%dHitMapSec", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); + } + + // There are 3 silicon stations + for (int i = 0; i < 3; i++) { + mHistograms[TString::Format("fsi%dHitMap", i).Data()] = new TH2F(TString::Format("fsi%dHitMap", i), TString::Format("FSI Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); + mHistograms[TString::Format("fsi%dHitMapZ", i).Data()] = new TH2F(TString::Format("fsi%dHitMapZ", i), TString::Format("FSI Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); + + mHistograms[TString::Format("fsi%dHitMapR", i).Data()] = new TH1F(TString::Format("fsi%dHitMapR", i), TString::Format("FSI Layer %d; r (cm); ", i), 500, 0, 50); + mHistograms[TString::Format("fsi%dHitMapPhi", i).Data()] = new TH1F(TString::Format("fsi%dHitMapPhi", i), TString::Format("FSI Layer %d; phi; ", i), 320, 0, TMath::Pi() * 2 + 0.1); + } + + } // mGenHistograms + LOG_DEBUG << "StFwdTrackMaker::Init" << endm; return kStOK; }; @@ -352,84 +570,68 @@ void StFwdTrackMaker::loadFttHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdD StEvent *event = (StEvent *)GetDataSet("StEvent"); string fttFromSource = mFwdConfig.get( "Source:ftt", "" ); - if (!event){ + if (!event){ LOG_ERROR << "No StEvent, cannot load Ftt Data" << endm; return; } + // Load GEANT hits directly if requested + if ( "GEANT" == fttFromSource ) { + LOG_DEBUG << "Loading sTGC hits directly from GEANT hits" << endm; + loadFttHitsFromGEANT( mcTrackMap, hitMap, count ); + return; + } + StFttCollection *col = event->fttCollection(); // From Data if ( col || "DATA" == fttFromSource ) { loadFttHitsFromStEvent( mcTrackMap, hitMap, count ); return; } - - // Load GEANT hits directly if requested - if ( true ) { - LOG_DEBUG << "Try loading sTGC hits directly from GEANT hits" << endm; - loadFttHitsFromGEANT( mcTrackMap, hitMap, count ); - return; - } } // loadFttHits void StFwdTrackMaker::loadFttHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ LOG_DEBUG << "Loading FTT Hits from Data" << endm; StEvent *event = (StEvent *)GetDataSet("StEvent"); StFttCollection *col = event->fttCollection(); - size_t numFwdHitsPrior = mFwdHitsFtt.size(); + + mTreeData.fttN = 0; if ( col && col->numberOfPoints() > 0 ){ LOG_DEBUG << "The Ftt Collection has " << col->numberOfPoints() << " points" << endm; TMatrixDSym hitCov3(3); - const double sigXY = 0.2; // + const double sigXY = 0.2; // hitCov3(0, 0) = sigXY * sigXY; hitCov3(1, 1) = sigXY * sigXY; hitCov3(2, 2) = 4; // unused since they are loaded as points on plane - static const double mm_to_cm = 0.1; for ( auto point : col->points() ){ + + FwdHit *hit = new FwdHit(count++, point->xyz().x()/10.0, point->xyz().y()/10.0, point->xyz().z(), -point->plane(), 0, hitCov3, nullptr); + mFttHits.push_back( TVector3( point->xyz().x()/10.0, point->xyz().y()/10.0, point->xyz().z() ) ); + if ( mGenHistograms ) { + mHistograms[TString::Format("stgc%dHitMapSec", point->plane()).Data()]->Fill(point->xyz().x()/10.0, point->xyz().y()/10.0); + } + // Add the hit to the hit map + hitMap[hit->getSector()].push_back(hit); - float xcm = point->xyz().x()*mm_to_cm; - float ycm = point->xyz().y()*mm_to_cm; - float zcm = point->xyz().z(); - - // get the track id - int track_id = point->idTruth(); - shared_ptr mcTrack = nullptr; - if ( mcTrackMap.count(track_id) ) { - mcTrack = mcTrackMap[track_id]; - LOG_DEBUG << "Adding McTrack to FTT hit: " << track_id << endm; + if (mGenTree && (unsigned)mTreeData.fttN < MAX_TREE_ELEMENTS) { + LOG_DEBUG << "FttPoint( " << TString::Format( "[plane=%d, quad=%d, nClu=%d]", point->plane(), point->quadrant(), point->nClusters() ) << point->xyz().x()/10.0 << ", " << point->xyz().y()/10.0 << ", " << point->xyz().z() << " )" << endm; + mTreeData.fttX.push_back( point->xyz().x()/10.0 ); + mTreeData.fttY.push_back( point->xyz().y()/10.0 ); + mTreeData.fttZ.push_back( point->xyz().z() ); + mTreeData.fttTrackId.push_back( 0 ); + mTreeData.fttVolumeId.push_back( point->plane() ); + mTreeData.fttPt.push_back( 0 ); + mTreeData.fttVertexId.push_back( 0 ); + mTreeData.fttN++; } + } - mFwdHitsFtt.push_back(FwdHit(count++, // id - xcm, ycm, zcm, - -point->plane(), // volume id - kFttId, // detid - track_id, // track id - hitCov3, // covariance matrix - mcTrack) // mcTrack - ); - mFttHits.push_back( TVector3( xcm, ycm, zcm) ); - } // end of loop over points + return; } else { LOG_DEBUG << "The Ftt Collection is EMPTY points" << endm; } - - // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses - size_t numFwdHitsPost = mFwdHitsFtt.size(); - for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ - FwdHit *hit = &(mFwdHitsFtt[ iFwdHit ]); - // Add the hit to the hit map - if ( hit->getLayer() >= 0 ) - hitMap[hit->getSector()].push_back(hit); - // add to MC track map - if ( hit->getMcTrack() ){ - hit->getMcTrack()->addFttHit(hit); - } - } - - if ( numFwdHitsPost != numFwdHitsPrior ){ - LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FTT hits from StEvent" << endm; - } + LOG_DEBUG << "Number of FTT in TTree: " << mTreeData.fttN << endm; } void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ @@ -437,22 +639,27 @@ void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrack // STGC Hits St_g2t_fts_hit *g2t_stg_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_stg_hit"); - size_t numFwdHitsPrior = mFwdHitsFtt.size(); + + mTreeData.fttN = 0; if (!g2t_stg_hits){ - LOG_WARN << "geant/g2t_stg_hit is empty" << endm; + LOG_WARN << "geant/g2t_stg_hit is empty" << endm; return; } // make the Covariance Matrix once and then reuse TMatrixDSym hitCov3(3); - const double sigXY = 0.02; + const double sigXY = 0.01; hitCov3(0, 0) = sigXY * sigXY; hitCov3(1, 1) = sigXY * sigXY; - hitCov3(2, 2) = 0.1; // unused since they are loaded as points on plane + hitCov3(2, 2) = 1.0; // unused since they are loaded as points on plane int nstg = g2t_stg_hits->GetNRows(); LOG_DEBUG << "This event has " << nstg << " stg hits in geant/g2t_stg_hit " << endm; + if ( mGenHistograms ) { + mHistograms["nHitsSTGC"]->Fill(nstg); + } + bool filterGEANT = mFwdConfig.get( "Source:fttFilter", false ); for (int i = 0; i < nstg; i++) { @@ -468,258 +675,152 @@ void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrack if ( volume_id % 2 ==0 ) continue; - float x = git->x[0];// + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso - float y = git->x[1];// + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso + float x = git->x[0] + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso + float y = git->x[1] + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso float z = git->x[2]; - if (plane_id < 0 || plane_id >= 4) { - continue; - } - mFwdHitsFtt.push_back( - FwdHit( - count++, // id - x, y, z, // position - -plane_id, // volume id - kFttId, // detid - track_id, // track id - hitCov3, // covariance matrix - mcTrackMap[track_id] // mcTrack - ) - ); - mFttHits.push_back( TVector3( x, y, z ) ); - } // loop on hits - - // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses - size_t numFwdHitsPost = mFwdHitsFtt.size(); - for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ - FwdHit *hit = &(mFwdHitsFtt[ iFwdHit ]); - // Add the hit to the hit map - if ( hit->getLayer() >= 0 ) - hitMap[hit->getSector()].push_back(hit); - if ( dynamic_cast(hit)->_mcTrack ){ - dynamic_cast(hit)->_mcTrack->addFttHit(hit); + + if (mGenTree && (unsigned)mTreeData.fttN < MAX_TREE_ELEMENTS) { + mTreeData.fttX.push_back( x ); + mTreeData.fttY.push_back( y ); + mTreeData.fttZ.push_back( z ); + mTreeData.fttTrackId.push_back( track_id ); + mTreeData.fttVolumeId.push_back( plane_id ); + mTreeData.fttPt.push_back( mcTrackMap[track_id]->mPt ); + mTreeData.fttVertexId.push_back( mcTrackMap[track_id]->mStartVertex ); + mTreeData.fttN++; + } else if ( mGenTree ){ + LOG_WARN << "Truncating hits in TTree output" << endm; } - } - if ( numFwdHitsPost != numFwdHitsPrior ){ - LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from MuDst" << endm; - } - -} // loadFttHits - -/** - * @brief Loads FST hits from various sources into the hitmap and McTrackMap (if availabale) - * - * Order of precedence: - * MuDst StMuFstCollection (Data) - * StEvent StFstHitCollection (Data or slowsim) - * StEvent StRndHitCollection (fast sim) - * GEANT St_g2t_fts_hit (starsim only) - note if rasterizer is active this takes priority over FastSim - * - * @param mcTrackMap : MC track map if running sim - * @param hitMap : FST hitmap to populate - * @param count : number of hits loaded - */ -int StFwdTrackMaker::loadFstHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap ){ - - int count = loadFstHitsFromMuDst(mcTrackMap, hitMap); - if ( count > 0 ) return count; // only load from one source at a time - - count += loadFstHitsFromStEvent(mcTrackMap, hitMap); - if ( count > 0 ) return count; // only load from one source at a time - - bool siRasterizer = mFwdConfig.get( "SiRasterizer:active", false ); - - if ( !siRasterizer ) count += loadFstHitsFromStRnDHits( mcTrackMap, hitMap ); - if ( count > 0 ) return count; // only load from one source at a time + if ( mGenHistograms ){ + mHistograms["stgc_volume_id"]->Fill(volume_id); + } - return loadFstHitsFromGEANT( mcTrackMap, hitMap ); -} // loadFstHits + if (plane_id < 4 && plane_id >= 0) { + if ( mGenHistograms ){ + mHistograms[TString::Format("stgc%dHitMap", plane_id).Data()]->Fill(x, y); + } + } else { + continue; + } -int StFwdTrackMaker::loadFstHitsFromMuDst( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ - int count = 0; - StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); - if(!mMuDstMaker) { - LOG_WARN << " No MuDstMaker ... bye-bye" << endm; - return 0; - } - StMuDst *mMuDst = mMuDstMaker->muDst(); - if(!mMuDst) { - LOG_WARN << " No MuDst ... bye-bye" << endm; - return 0; - } + // this rejects GEANT hits with eta -999 - do we understand this effect? + if ( filterGEANT ) { + if ( mcTrackMap[track_id] && fabs(mcTrackMap[track_id]->mEta) > 5.0 ){ + + if ( mGenHistograms ) + mHistograms[TString::Format("stgc%dHitMapSec", plane_id).Data()]->Fill(x, y); + continue; + } else if ( mcTrackMap[track_id] && fabs(mcTrackMap[track_id]->mEta) < 5.0 ){ + if ( mGenHistograms ) mHistograms[TString::Format("stgc%dHitMapPrim", plane_id).Data()]->Fill(x, y); + } + } - StMuFstCollection * fst = mMuDst->muFstCollection(); - if (!fst) { - LOG_WARN << "No StMuFstCollection ... bye-bye" << endm; - return 0; - } + FwdHit *hit = new FwdHit(count++, x, y, z, -plane_id, track_id, hitCov3, mcTrackMap[track_id]); - size_t numFwdHitsPrior = mFwdHitsFst.size(); - LOG_INFO << "Loading " << fst->numberOfHits() << " StMuFstHits" << endm; - TMatrixDSym hitCov3(3); - for ( unsigned int index = 0; index < fst->numberOfHits(); index++){ - StMuFstHit * muFstHit = fst->getHit( index ); - - float vR = muFstHit->localPosition(0); - float vPhi = muFstHit->localPosition(1); - float vZ = muFstHit->localPosition(2); - - const float dz0 = fabs( vZ - mFstZFromGeom[0] ); - const float dz1 = fabs( vZ - mFstZFromGeom[1] ); - const float dz2 = fabs( vZ - mFstZFromGeom[2] ); - static const float fstThickness = 2.0; // thickness in cm between inner and outer on sigle plane - - // assign disk according to which z value the hit has, within the z-plane thickness - int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); - - float x0 = vR * cos( vPhi ); - float y0 = vR * sin( vPhi ); - hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); - - LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; - mFstHits.push_back( TVector3( x0, y0, vZ) ); - - // we use d+4 so that both FTT and FST start at 4 - mFwdHitsFst.push_back( - FwdHit( - count++, // id - x0, y0, vZ, // position - d+4, // volume id - kFstId, // detid - 0, // track id - hitCov3, // covariance matrix - nullptr // mcTrack - ) - ); - } // index - - // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses - size_t numFwdHitsPost = mFwdHitsFst.size(); - for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ - FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); // Add the hit to the hit map - if ( hit->getLayer() >= 0 ) - hitMap[hit->getSector()].push_back(hit); - } + hitMap[hit->getSector()].push_back(hit); + mFttHits.push_back( TVector3( x, y, z ) ); - if ( numFwdHitsPost != numFwdHitsPrior ){ - LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from MuDst" << endm; - } + // Add hit pointer to the track + if (mcTrackMap[track_id]){ + mcTrackMap[track_id]->addHit(hit); + } else { + LOG_ERROR << "Cannot find MC track for GEANT hit (FTT), track_id = " << track_id << endm; + } + } // loop on hits - // TODO add to hitmap - return count; -} // loadFstHitsFromMuDst + if (mGenTree){ + LOG_INFO << "Saving " << mTreeData.fttN << " hits in Tree" << endm; + } +} // loadFttHits -int StFwdTrackMaker::loadFstHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ - int count = 0; +void StFwdTrackMaker::loadFstHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ StEvent *event = (StEvent *)GetDataSet("StEvent"); - if (!event) { - LOG_WARN << "No StEvent, cannot load FST hits from StEvent StFstHitCollection" << endm; - return 0; - } - LOG_DEBUG << "Got StEvent, loading Fst Hits" << endm; StFstHitCollection *fstHitCollection = event->fstHitCollection(); - size_t numFwdHitsPrior = mFwdHitsFst.size(); - if ( fstHitCollection && fstHitCollection->numberOfHits() > 0){ + if ( fstHitCollection ){ // reuse this to store cov mat TMatrixDSym hitCov3(3); LOG_DEBUG << "StFstHitCollection is NOT NULL, loading hits" << endm; for ( unsigned int iw = 0; iw < kFstNumWedges; iw++ ){ StFstWedgeHitCollection * wc = fstHitCollection->wedge( iw ); - if ( !wc ) continue; + for ( unsigned int is = 0; is < kFstNumSensorsPerWedge; is++ ){ StFstSensorHitCollection * sc = wc->sensor( is ); - if ( !sc ) continue; + StSPtrVecFstHit fsthits = sc->hits(); + mTreeData.fstN = 0; for ( unsigned int ih = 0; ih < fsthits.size(); ih++ ){ float vR = fsthits[ih]->localPosition(0); float vPhi = fsthits[ih]->localPosition(1); float vZ = fsthits[ih]->localPosition(2); - const float dz0 = fabs( vZ - mFstZFromGeom[0] ); - const float dz1 = fabs( vZ - mFstZFromGeom[1] ); - const float dz2 = fabs( vZ - mFstZFromGeom[2] ); - static const float fstThickness = 3.0; // thickness in cm between inner and outer on sigle plane + const float dz0 = fabs( vZ - 151.75 ); + const float dz1 = fabs( vZ - 165.248 ); + const float dz2 = fabs( vZ - 178.781 ); + + int d = 0 * ( dz0 < 1.0 ) + 1 * ( dz1 < 1.0 ) + 2 * ( dz2 < 1.0 ); + - // assign disk according to which z value the hit has, within the z-plane thickness - int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); float x0 = vR * cos( vPhi ); float y0 = vR * sin( vPhi ); hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); - LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; + LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; mFstHits.push_back( TVector3( x0, y0, vZ) ); - int track_id = fsthits[ih]->idTruth(); - LOG_DEBUG << "FST Hit: idTruth = " << track_id << endm; - shared_ptr mcTrack = nullptr; - if ( mcTrackMap.count(track_id) ) { - mcTrack = mcTrackMap[track_id]; - LOG_DEBUG << "Adding McTrack to FST hit" << endm; - } - // we use d+4 so that both FTT and FST start at 4 - mFwdHitsFst.push_back( - FwdHit( - count++, // id - x0, y0, vZ, // position - d+4, // volume id - kFstId, // detid - track_id, // mc track id - hitCov3, // covariance matrix - mcTrack // mcTrack - ) - ); - // store a pointer to the original StFstHit - mFwdHitsFst.back()._hit = fsthits[ih]; + FwdHit *hit = new FwdHit(count++, x0, y0, vZ, d, 0, hitCov3, nullptr); + // Add the hit to the hit map + hitMap[hit->getSector()].push_back(hit); + + mTreeData.fstX.push_back( x0 ); + mTreeData.fstY.push_back( y0 ); + mTreeData.fstZ.push_back( vZ ); + + mTreeData.fstN++; } } // loop is } // loop iw - LOG_DEBUG << " FOUND " << mFstHits.size() << " FST HITS in StFstHitCollection" << endm; + LOG_DEBUG << " FOUND " << mFstHits.size() << " FST HITS" << endm; + return; } // fstHitCollection - // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses - size_t numFwdHitsPost = mFwdHitsFst.size(); - for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ - FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); - // Add the hit to the hit map - if ( hit->getLayer() >= 0 ) - hitMap[hit->getSector()].push_back(hit); - // add to MC track map - if ( hit->getMcTrack() ){ - hit->getMcTrack()->addFstHit(hit); - } + + StRnDHitCollection *rndCollection = nullptr; + if (nullptr != event) { + rndCollection = event->rndHitCollection(); } - if ( numFwdHitsPost != numFwdHitsPrior ){ - LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from StEvent" << endm; + bool siRasterizer = mFwdConfig.get( "SiRasterizer:active", false ); + if ( siRasterizer || rndCollection == nullptr ){ + LOG_DEBUG << "Loading Fst hits from GEANT with SiRasterizer" << endm; + loadFstHitsFromGEANT( mcTrackMap, hitMap, count ); + } else { + LOG_DEBUG << "Loading Fst hits from StEvent" << endm; + loadFstHitsFromStEvent( mcTrackMap, hitMap, count ); } - return count; -} //loadFstHitsFromStEvent +} // loadFstHits + +void StFwdTrackMaker::loadFstHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ -int StFwdTrackMaker::loadFstHitsFromStRnDHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ - LOG_DEBUG << "Looking for FST hits in StEvent StRnDHit Collection" << endm; - int count = 0; // Get the StEvent handle StEvent *event = (StEvent *)GetDataSet("StEvent"); - if (!event) { - LOG_DEBUG << "No StEvent, cannot load FST FastSim hits from StEvent StRndHitCollection" << endm; - return 0; - } + if (!event) + return; - size_t numFwdHitsPrior = mFwdHitsFst.size(); StRnDHitCollection *rndCollection = event->rndHitCollection(); - if (!rndCollection) return 0; const StSPtrVecRnDHit &hits = rndCollection->hits(); // we will reuse this to hold the cov mat TMatrixDSym hitCov3(3); - + + mTreeData.fstN = 0; for (unsigned int fsthit_index = 0; fsthit_index < hits.size(); fsthit_index++) { StRnDHit *hit = hits[fsthit_index]; - + if ( hit->layer() > 6 ){ // skip sTGC hits here continue; @@ -734,64 +835,54 @@ int StFwdTrackMaker::loadFstHitsFromStRnDHits( FwdDataSource::McTrackMap_t &mcTr hitCov3(1,0) = covmat[1][0]; hitCov3(1,1) = covmat[1][1]; hitCov3(1,2) = covmat[1][2]; hitCov3(2,0) = covmat[2][0]; hitCov3(2,1) = covmat[2][1]; hitCov3(2,2) = covmat[2][2]; - mFwdHitsFst.push_back( - FwdHit( - count++, // id - hit->position().x(), hit->position().y(), hit->position().z(), // position - hit->layer(), // volume id - kFstId, // detid - hit->idTruth(), // mc track id - hitCov3, // covariance matrix - mcTrackMap[hit->idTruth()] // mcTrack - ) - ); - mFstHits.push_back( TVector3( hit->position().x(), hit->position().y(), hit->position().z()) ); - } + FwdHit *fhit = new FwdHit(count++, hit->position().x(), hit->position().y(), hit->position().z(), hit->layer(), hit->idTruth(), hitCov3, mcTrackMap[hit->idTruth()]); + size_t index = hit->layer()-4; + if (mGenHistograms && index < 3 ){ + ((TH2*)mHistograms[TString::Format("fsi%luHitMapZ", index).Data()]) -> Fill( hit->position().x(), hit->position().y(), hit->position().z() ); + } - // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses - size_t numFwdHitsPost = mFwdHitsFst.size(); - for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ - FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); // Add the hit to the hit map - if ( hit->getLayer() >= 0 ) - hitMap[hit->getSector()].push_back(hit); - } - if ( numFwdHitsPost != numFwdHitsPrior ){ - LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from StEvent FastSim" << endm; - } + hitMap[fhit->getSector()].push_back(fhit); + mFstHits.push_back( TVector3( hit->position().x(), hit->position().y(), hit->position().z()) ); - return count; + mTreeData.fstX.push_back( hit->position().x() ); + mTreeData.fstY.push_back( hit->position().y() ); + mTreeData.fstZ.push_back( hit->position().z() ); + mTreeData.fstTrackId.push_back( hit->idTruth() ); + + mTreeData.fstN++; + + } } //loadFstHitsFromStEvent -int StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap ){ - int count = 0; - LOG_DEBUG << "Looking for FST hits in geant struct" << endm; +void StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ /************************************************************/ // Load FSI Hits from GEANT St_g2t_fts_hit *g2t_fsi_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_fsi_hit"); - if ( !g2t_fsi_hits ){ - LOG_DEBUG << "No g2t_fts_hits, cannot load FST hits from GEANT" << endm; - return 0; - } + if ( !g2t_fsi_hits ) + return; int nfsi = g2t_fsi_hits->GetNRows(); - size_t numFwdHitsPrior = mFwdHitsFst.size(); + // reuse this to store cov mat TMatrixDSym hitCov3(3); + + if ( mGenHistograms ) mHistograms["nHitsFSI"]->Fill(nfsi); + mTreeData.fstN = 0; for (int i = 0; i < nfsi; i++) { g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_fsi_hits->At(i); - + if (0 == git) continue; // geant hit - + int track_id = git->track_p; int volume_id = git->volume_id; // 4, 5, 6 int d = volume_id / 1000; // disk id - + int plane_id = d - 4; float x = git->x[0]; float y = git->x[1]; @@ -799,61 +890,47 @@ int StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackM if (mSiRasterizer->active()) { TVector3 rastered = mSiRasterizer->raster(TVector3(git->x[0], git->x[1], git->x[2])); - LOG_INFO << TString::Format("Rastered: %f %f %f -> %f %f %f", git->x[0], git->x[1], git->x[2], rastered.X(), rastered.Y(), rastered.Z()) << endm; + + if ( mGenHistograms ) { + mHistograms["fsiHitDeltaR"]->Fill(std::sqrt(x * x + y * y) - rastered.Perp()); + mHistograms["fsiHitDeltaPhi"]->Fill(std::atan2(y, x) - rastered.Phi()); + } x = rastered.X(); y = rastered.Y(); - } else { - LOG_INFO << "Using GEANT FST hit positions without rasterization" << endm; } - if (plane_id > 3 || plane_id < 0) { + + if ( mGenHistograms ) mHistograms["fsi_volume_id"]->Fill(d); + + if (plane_id < 3 && plane_id >= 0) { + + if ( mGenHistograms ) { + mHistograms[TString::Format("fsi%dHitMap", plane_id).Data()]->Fill(x, y); + mHistograms[TString::Format("fsi%dHitMapR", plane_id).Data()]->Fill(std::sqrt(x * x + y * y)); + mHistograms[TString::Format("fsi%dHitMapPhi", plane_id).Data()]->Fill(std::atan2(y, x) + TMath::Pi()); + } + } else { continue; } hitCov3 = makeSiCovMat( TVector3( x, y, z ), mFwdConfig ); - mFwdHitsFst.push_back( - FwdHit( - count++, // id - x, y, z, // position - d, // volume id - kFstId, // detid - track_id, // mc track id - hitCov3, // covariance matrix - mcTrackMap[track_id] // mcTrack - ) - ); + FwdHit *hit = new FwdHit(count++, x, y, z, d, track_id, hitCov3, mcTrackMap[track_id]); mFstHits.push_back( TVector3( x, y, z ) ); - } - // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses - size_t numFwdHitsPost = mFwdHitsFst.size(); - for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ - FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); - // Add the hit to the hit map - if ( hit->getLayer() >= 0 ) - hitMap[hit->getSector()].push_back(hit); + mTreeData.fstX.push_back( x ); + mTreeData.fstY.push_back( y ); + mTreeData.fstZ.push_back( z ); + mTreeData.fstTrackId.push_back( track_id ); - // add to MC track map - if ( hit->getMcTrack() ) - hit->getMcTrack()->addFstHit(hit); - } - if ( numFwdHitsPost != numFwdHitsPrior ){ - LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from GEANT" << endm; - } + mTreeData.fstN++; - return count; + // Add the hit to the hit map + hitMap[hit->getSector()].push_back(hit); + } } // loadFstHitsFromGEANT -/** - * Loads the Monte Carlo (MC) tracks from the GEANT simulation data. - * - * @param mcTrackMap A reference to the MC track map. - * - * @return The number of forward tracks. - * - * @throws None. - */ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ + LOG_DEBUG << "Looking for GEANT sim vertex info" << endm; St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); @@ -861,15 +938,9 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ if ( g2t_vertex != nullptr ) { // Set the MC Vertex for track fitting g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0); - TMatrixDSym cov; - cov.ResizeTo(3, 3); - cov(0, 0) = 0.001; - cov(1, 1) = 0.001; - cov(2, 2) = 0.001; - mForwardTracker->setEventVertex( TVector3( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ), cov ); + mForwardTracker->setEventVertex( TVector3( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ) ); } - // Get geant tracks St_g2t_track *g2t_track = (St_g2t_track *)GetDataSet("geant/g2t_track"); @@ -877,7 +948,10 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ return 0; size_t nShowers = 0; + + mTreeData.mcN = 1; LOG_DEBUG << g2t_track->GetNRows() << " mc tracks in geant/g2t_track " << endm; + if ( mGenHistograms ) mHistograms["nMcTracks"]->Fill(g2t_track->GetNRows()); for (int irow = 0; irow < g2t_track->GetNRows(); irow++) { g2t_track_st *track = (g2t_track_st *)g2t_track->At(irow); @@ -889,38 +963,65 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ float pt2 = track->p[0] * track->p[0] + track->p[1] * track->p[1]; float pt = std::sqrt(pt2); float eta = track->eta; - TVector3 pp( track->p[0], track->p[1], track->p[2] ); float phi = std::atan2(track->p[1], track->p[0]); //track->phi; int q = track->charge; - // sometimes the track->eta is wrong, pt, phi - if (!mcTrackMap[track_id] ) - mcTrackMap[track_id] = shared_ptr(new McTrack(pp.Pt(), pp.Eta(), pp.Phi(), q, track->start_vertex_p)); + + if (!mcTrackMap[track_id] ) + mcTrackMap[track_id] = shared_ptr(new McTrack(pt, eta, phi, q, track->start_vertex_p)); + + if (mGenTree && (unsigned)mTreeData.mcN < MAX_TREE_ELEMENTS) { + mTreeData.mcPt.push_back( pt ); + mTreeData.mcEta.push_back( eta ); + mTreeData.mcPhi.push_back( phi ); + mTreeData.mcCharge.push_back( q ); + mTreeData.mcVertexId.push_back( track->start_vertex_p ); + + if (track->is_shower) + nShowers++; + + mTreeData.mcN++; + } else if ( mGenTree ) { + LOG_WARN << "Truncating Mc tracks in TTree output" << endm; + } } // loop on track (irow) + // now check the Mc tracks against the McEvent filter size_t nForwardTracks = 0; size_t nForwardTracksNoThreshold = 0; for (auto mctm : mcTrackMap ){ if ( mctm.second == nullptr ) continue; + + if ( mGenHistograms ){ + mHistograms[ "McEventPt" ] ->Fill( mctm.second->mPt ); + mHistograms[ "McEventEta" ] ->Fill( mctm.second->mEta ); + mHistograms[ "McEventPhi" ] ->Fill( mctm.second->mPhi ); + } + if ( mctm.second->mEta > 2.5 && mctm.second->mEta < 4.0 ){ + + if ( mGenHistograms ){ + mHistograms[ "McEventFwdPt" ] ->Fill( mctm.second->mPt ); + mHistograms[ "McEventFwdEta" ] ->Fill( mctm.second->mEta ); + mHistograms[ "McEventFwdPhi" ] ->Fill( mctm.second->mPhi ); + } + nForwardTracksNoThreshold++; if ( mctm.second->mPt > 0.05 ) nForwardTracks++; } } // loop on mcTrackMap + + if ( mGenHistograms ) { + mHistograms[ "nMcTracksFwd" ]->Fill( nForwardTracks ); + mHistograms[ "nMcTracksFwdNoThreshold" ]->Fill( nForwardTracksNoThreshold ); + } + + return nForwardTracks; } // loadMcTracks -/** - * Load FCS data from StEvent for ECAL/HCAL clusters and Preshower hits (EPD). - * - * @param None - * - * @return None - * - * @throws None - */ void StFwdTrackMaker::loadFcs( ) { StEvent *stEvent = static_cast(GetInputDS("StEvent")); StFcsDb* fcsDb=static_cast(GetDataSet("fcsDb")); @@ -934,6 +1035,8 @@ void StFwdTrackMaker::loadFcs( ) { StEpdGeom epdgeo; + mTreeData.fcsN = 0; + // LOAD ECAL / HCAL CLUSTERS for ( int idet = 0; idet < 4; idet++ ){ StSPtrVecFcsCluster& clusters = fcsCol->clusters(idet); @@ -943,8 +1046,13 @@ void StFwdTrackMaker::loadFcs( ) { StThreeVectorD xyz = fcsDb->getStarXYZfromColumnRow(clu->detectorId(),clu->x(),clu->y()); mFcsClusters.push_back( TVector3( xyz.x(), xyz.y(), xyz.z() - 2 ) ); mFcsClusterEnergy.push_back( clu->energy() ); - } // i - } // idet + + mTreeData.fcsX.push_back( xyz.x() ); + mTreeData.fcsY.push_back( xyz.y() ); + mTreeData.fcsZ.push_back( xyz.z() - 2 ); + mTreeData.fcsDet.push_back( idet ); + } + } // LOAD PRESHOWER HITS (EPD) for ( int det = 4; det < 6; det ++ ) { @@ -965,142 +1073,37 @@ void StFwdTrackMaker::loadFcs( ) { double x0 = (x[0] + x[1] + x[2] + x[3]) / 4.0; double y0 = (y[0] + y[1] + y[2] + y[3]) / 4.0; mFcsPreHits.push_back( TVector3( x0, y0, zepd ) ); - } // if det - } // for i - } // for det -} // loadFcs -TVector3 StFwdTrackMaker::GetEventPrimaryVertex(){ - if ( mFwdVertexSource == kFwdVertexSourceNone ){ - // Note - maybe we will add beamline or assume some default - return TVector3(0, 0, 0); // the default vertex, but in general it should not be used - } - - if ( mFwdVertexSource != kFwdVertexSourceUnknown ){ - return mEventVertex; - } - - mEventVertexCov.ResizeTo(3, 3); - mEventVertexCov.Zero(); - double sig2 = 1; - mEventVertexCov(0, 0) = sig2; // default resolution - mEventVertexCov(1, 1) = sig2; - mEventVertexCov(2, 2) = sig2; - // if something is found it will overwrite this, if not - // it will indicate that we have searched and found nothing - mFwdVertexSource = kFwdVertexSourceNone; - - /***************************************************** - * Add Primary Vertex to the track - */ - St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); - if ( g2t_vertex != nullptr ) { - // Set the MC Vertex for track fitting - g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0); - - mEventVertexCov.ResizeTo(3, 3); - const double sigXY = 0.1; - const double sigZ = 10.0; - mEventVertexCov(0, 0) = pow(sigXY,2); - mEventVertexCov(1, 1) = pow(sigXY,2); - mEventVertexCov(2, 2) = pow(sigZ, 2); - auto rhc = TVectorD( 3 ); - rhc[0] = vert->ge_x[0]; - rhc[1] = vert->ge_x[1]; - rhc[2] = vert->ge_x[2]; - mEventVertex.SetXYZ( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ); - mFwdVertexSource = kFwdVertexSourceMc; - return mEventVertex; - } - - // or try the McEvent - StMcEvent *stMcEvent = static_cast(GetInputDS("StMcEvent")); - if (stMcEvent) { - LOG_INFO << "Setting Event Vertex from StMcEvent: " << stMcEvent << endm; - StThreeVectorF vertex = stMcEvent->primaryVertex()->position(); - mEventVertex.SetXYZ( vertex.x(), vertex.y(), vertex.z() ); - mFwdVertexSource = kFwdVertexSourceMc; - LOG_INFO << "FWD Tracking on event with MC Primary Vertex: " << mEventVertex.X() << ", " << mEventVertex.Y() << ", " << mEventVertex.Z() << endm; - - mEventVertexCov(0, 0) = 0.1 * 0.1; // default resolution - mEventVertexCov(1, 1) = 0.1 * 0.1; // default resolution - mEventVertexCov(2, 2) = 0.1 * 0.1; // default resolution - return mEventVertex; - } else { - LOG_DEBUG << "No available Mc Primary Vertex" << endm; - } - - // MuDst only for now - int count = 0; - StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); - if(mMuDstMaker && mMuDstMaker->muDst() && mMuDstMaker->muDst()->primaryVertex() ) { - auto muPV = mMuDstMaker->muDst()->primaryVertex(); - mEventVertex.SetX(muPV->position().x()); - mEventVertex.SetY(muPV->position().y()); - mEventVertex.SetZ(muPV->position().z()); - mFwdVertexSource = kFwdVertexSourceTpc; - return mEventVertex; - } else { - LOG_DEBUG << "FWD Tracking on event without available Mu Primary Vertex" << endm; - StEvent *stEvent = static_cast(GetInputDS("StEvent")); - if (!stEvent) return mEventVertex; - StBTofCollection *btofC = stEvent->btofCollection(); - if (!btofC) { - LOG_WARN << "Cannot get BTOF collections, Cannot use VPD vertex" << endm; - return mEventVertex; - } - - StBTofHeader * btofHeader = btofC->tofHeader(); - if (!btofHeader){ - LOG_WARN << "Cannot get BTOF Header, Cannot use VPD vertex" << endm; - return mEventVertex; - } + mTreeData.fcsX.push_back( x0 ); + mTreeData.fcsY.push_back( y0 ); + mTreeData.fcsZ.push_back( zepd ); + mTreeData.fcsDet.push_back( det ); - int nEast = btofHeader->numberOfVpdHits( east ); - int nWest = btofHeader->numberOfVpdHits( west ); - int nTof = btofC->tofHits().size(); - - if ( btofHeader->vpdVz() && fabs(btofHeader->vpdVz()) < 100 ){ - // default event vertex - LOG_DEBUG << "FWD Tracking on event using VPD z vertex: (, 0, 0, " << btofHeader->vpdVz() << " )" << endm; - mFwdVertexSource = kFwdVertexSourceVpd; - mEventVertex.SetXYZ( 0, 0, btofHeader->vpdVz() ); - return mEventVertex; + } } } - return mEventVertex; -} +} // loadFcs + //________________________________________________________________________ int StFwdTrackMaker::Make() { // START time for measuring tracking long long itStart = FwdTrackerUtils::nowNanoSecond(); - StEvent *stEvent = static_cast(GetInputDS("StEvent")); - if (!stEvent) return kStOk; - - /**********************************************************************/ - // Access forward track and hit maps + // Access forward Tracker maps FwdDataSource::McTrackMap_t &mcTrackMap = mForwardData->getMcTracks(); FwdDataSource::HitMap_t &hitMap = mForwardData->getFttHits(); FwdDataSource::HitMap_t &fsiHitMap = mForwardData->getFstHits(); - - /**********************************************************************/ - // get the primary vertex for use with FWD tracking - mFwdVertexSource = StFwdTrackMaker::kFwdVertexSourceUnknown; - GetEventPrimaryVertex(); - LOG_DEBUG << "FWD Vertex Source: " << mFwdVertexSource << endm; - if ( mFwdVertexSource == kFwdVertexSourceNone ){ - // TODO: add clean support for beamline constraints - setIncludePrimaryVertexInFit( false ); - } else if ( mFwdVertexSource == kFwdVertexSourceUnknown ){ - LOG_WARN << "FwdVertexSource=Unknown even after looking, shouldnt be possible. Not using primary vertex in forward tracking" << endm; - // this should not be possible - setIncludePrimaryVertexInFit( false ); - } else { - LOG_DEBUG << "Setting FWD event vertex to: " << TString::Format("mEventVertex=(%0.3f+/-%0.3f, %0.3f+/-%0.3f, %0.3f+/-%0.3f)", mEventVertex.X(), sqrt(mEventVertexCov(0, 0)), mEventVertex.Y(), sqrt(mEventVertexCov(1, 1)), mEventVertex.Z(), sqrt(mEventVertexCov(2, 2)) ) << endm; - mForwardTracker->setEventVertex( mEventVertex, mEventVertexCov ); - } + + // clear vectors for visualization OBJ hits + mFttHits.clear(); + mFstHits.clear(); + mFcsPreHits.clear(); + mFcsClusters.clear(); + mFwdTracks.clear(); + + // default event vertex + mForwardTracker->setEventVertex( TVector3( 0, 0, 0 ) ); /**********************************************************************/ // Load MC tracks @@ -1113,18 +1116,18 @@ int StFwdTrackMaker::Make() { LOG_DEBUG << "We have " << nForwardTracks << " forward MC tracks" << endm; /**********************************************************************/ - // Load sTGC + // Load sTGC LOG_DEBUG << ">>StFwdTrackMaker::loadFttHits" << endm; if ( IAttr("useFtt") ) { loadFttHits( mcTrackMap, hitMap ); } + /**********************************************************************/ // Load FST + LOG_DEBUG << ">>StFwdTrackMaker::loadFstHits" << endm; if ( IAttr("useFst") ) { - LOG_DEBUG << ">>StFwdTrackMaker::loadFstHits" << endm; - int fstCount = loadFstHits( mcTrackMap, fsiHitMap ); - LOG_DEBUG << "Loaded " << fstCount << " FST hits" << endm; + loadFstHits( mcTrackMap, fsiHitMap ); } /**********************************************************************/ @@ -1134,84 +1137,104 @@ int StFwdTrackMaker::Make() { loadFcs(); } - /**********************************************************************/ - // Print out the MC tracks and their hit counts - for ( auto kv : mcTrackMap ){ - if ( kv.second == nullptr ) continue; - LOG_DEBUG << "MC Track: id=" << kv.first << ", nFTT=" << kv.second->mFttHits.size() << ", nFST=" << kv.second->mFstHits.size() << endm; - } - /**********************************************************************/ // Run Track finding + fitting LOG_DEBUG << ">>START Event Forward Tracking" << endm; - LOG_INFO << "\tFinding FWD Track Seeds" << endm; - mForwardTracker->findTrackSeeds(); - LOG_INFO << "\tFitting FWD Track Seeds" << endm; - // in principle we could filter the track seeds further if we wanted - mForwardTracker->doTrackFitting( mForwardTracker->getTrackSeeds() ); + mForwardTracker->doEvent(); LOG_DEBUG << "< getTrackSeeds().size() << " Track Seeds" << endm; - LOG_INFO << "< getTrackResults().size() << " GenFit Tracks" << endm; - /**********************************************************************/ + LOG_DEBUG << "< getRecoTracks().size() << " GenFit Tracks" << endm; + + FitVertex(); + + StEvent *stEvent = static_cast(GetInputDS("StEvent")); /**********************************************************************/ - // Output track visualization if configured to do so - if ( mVisualize ){ - std::vector genfitTracks; - for ( auto gtr : mForwardTracker->getTrackResults() ) { - if ( gtr.mIsFitConvergedFully == false ) continue; - genfitTracks.push_back( gtr.mTrack.get() ); - } + // Run Track finding + fitting + + const auto &genfitTracks = mForwardTracker -> globalTracks(); + if ( mVisualize /* && genfitTracks.size() > 0 && genfitTracks.size() < 200*/ ) { + const auto &seed_tracks = mForwardTracker -> getRecoTracks(); - if ( mVisualize && genfitTracks.size() > 0 && genfitTracks.size() < 400 && eventIndex < 50 ) { - const auto &seed_tracks = mForwardTracker -> getTrackSeeds(); - - ObjExporter woe; - woe.output( - TString::Format( "ev%lu", eventIndex ).Data(), - stEvent, - seed_tracks, genfitTracks, mRaveVertices, - mFttHits, mFstHits, mFcsPreHits, mFcsClusters, mFcsClusterEnergy ); - eventIndex++; - LOG_DEBUG << "Done Writing OBJ " << endm; - } else if (mVisualize && genfitTracks.size() == 0) { - LOG_DEBUG << "Skipping visualization, no FWD tracks" << endm; - } else if (mVisualize && genfitTracks.size() >= 400) { - LOG_DEBUG << "Skipping visualization, too many FWD tracks" << endm; - } + ObjExporter woe; + woe.output( + TString::Format( "ev%lu", eventIndex ).Data(), + stEvent, + seed_tracks, genfitTracks, mRaveVertices, + mFttHits, mFstHits, mFcsPreHits, mFcsClusters, mFcsClusterEnergy ); + eventIndex++; + LOG_DEBUG << "Done Writing OBJ " << endm; + } else if (mVisualize && genfitTracks.size() == 0) { + LOG_DEBUG << "Skipping visualization, no FWD tracks" << endm; + } else if (mVisualize && genfitTracks.size() >= 20) { + LOG_DEBUG << "Skipping visualization, too many FWD tracks" << endm; } - LOG_DEBUG << "Forward tracking on this event took " << (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6 << " ms" << endm; - if ( IAttr("fillEvent") ) { + // Fill Track Deltas in ttree for helpful alignment info + FillTrackDeltas(); + + LOG_INFO << "Forward tracking on this event took " << (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6 << " ms" << endm; + + if ( true && IAttr("fillEvent") ) { + if (!stEvent) { LOG_WARN << "No StEvent found. Forward tracks will not be saved" << endm; return kStWarn; } + FillEvent(); } // IAttr FillEvent + LOG_DEBUG << "Filling fwd Tree for event: " << GetIventNumber() << endm; + FillTTree(); return kStOK; } // Make -/** - * Creates a StFwdTrack object from a GenfitTrackResult. - * - * @param gtr The GenfitTrackResult object containing the track information. - * @param indexTrack The index of the track. - * - * @return A pointer to the created StFwdTrack object, or nullptr if the GenfitTrackResult is nullptr. - * - * @throws None. - */ + StFwdTrack * StFwdTrackMaker::makeStFwdTrack( GenfitTrackResult >r, size_t indexTrack ){ LOG_DEBUG << "StFwdTrackMaker::makeStFwdTrack()" << endm; - StFwdTrack *fwdTrack = new StFwdTrack( ); + StFwdTrack *fwdTrack = new StFwdTrack( ); + + auto track = gtr.track; + // if FST refit is available save that + if ( gtr.nFST > 0 && gtr.fstTrack != nullptr){ + LOG_DEBUG << "\tSave FST refit track since we have FST points" << endm; + track = gtr.fstTrack; + } else if (gtr.nFST > 0 && gtr.fstTrack == nullptr) { + LOG_WARN << "\tFST refit failed even though we have " << gtr.nFST << " FST points" << endm; + } + + // Fit failed beyond use + if ( track == nullptr ){ + LOG_DEBUG << "Track is nullptr, not saving StFwdTrack" << endm; + return nullptr; + } + + auto fitStatus = track->getFitStatus(); + if ( !fitStatus ) + return nullptr; + + // Fill charge and quality info + fwdTrack->setDidFitConverge( fitStatus->isFitConverged() ); + fwdTrack->setDidFitConvergeFully( fitStatus->isFitConvergedFully() ); + fwdTrack->setNumberOfFailedPoints( fitStatus->getNFailedPoints() ); + + fwdTrack->setNumberOfFitPoints( track->getNumPoints() ); + fwdTrack->setChi2( fitStatus->getChi2() ); + fwdTrack->setNDF( fitStatus->getNdf() ); + fwdTrack->setPval( fitStatus->getPVal() ); + + auto cr = track->getCardinalRep(); + // charge at first point + fwdTrack->setCharge( gtr.charge ); + + TVector3 p = cr->getMom( track->getFittedState( 0, cr )); + fwdTrack->setPrimaryMomentum( StThreeVectorD( gtr.momentum.X(), gtr.momentum.Y(), gtr.momentum.Z() ) ); + LOG_DEBUG << "Making StFwdTrack with " << TString::Format( "p=(%f, %f, %f)", fwdTrack->momentum().x(), fwdTrack->momentum().y(), fwdTrack->momentum().z() ) << endm; - /*******************************************************************************/ - // store the seed points for the track int nSeedPoints = 0; - for ( auto s : gtr.mSeed ){ + // store the seed points from FTT + for ( auto s : gtr.trackSeed ){ FwdHit * fh = static_cast( s ); if (!fh) continue; float cov[9]; @@ -1219,112 +1242,101 @@ StFwdTrack * StFwdTrackMaker::makeStFwdTrack( GenfitTrackResult >r, size_t ind cov[1] = fh->_covmat(0,1); cov[4] = fh->_covmat(1,1); cov[7] = fh->_covmat(2,1); cov[2] = fh->_covmat(0,2); cov[5] = fh->_covmat(1,2); cov[8] = fh->_covmat(2,2); - StFwdTrackSeedPoint p( - StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), - fh->_detid * 10 + fh->getSector(), // 10 * detid + sector - fh->getTrackId(), - cov - ); - if ( fh->isFst() ) - fwdTrack->mFSTPoints.push_back( p ); - else if ( fh->isFtt() ) - fwdTrack->mFTTPoints.push_back( p ); - + StFwdTrackSeedPoint p( StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), fh->getSector(), fh->getTrackId(), cov ); + fwdTrack->mFTTPoints.push_back( p ); nSeedPoints++; } - // set total number of seed points - fwdTrack->setNumberOfSeedPoints( nSeedPoints ); - int idt = 0; - double qual = 0; - idt = MCTruthUtils::dominantContribution(gtr.mSeed, qual); - fwdTrack->setMc( idt, qual*100 ); // QAtruth stored as UChar_t - LOG_DEBUG << "Dominant contribution: " << idt << " with quality " << qual << endm; + for ( auto s : gtr.fstSeed ){ + FwdHit * fh = static_cast( s ); + if (!fh) continue; + float cov[9]; + cov[0] = fh->_covmat(0,0); cov[3] = fh->_covmat(1,0); cov[6] = fh->_covmat(2,0); + cov[1] = fh->_covmat(0,1); cov[4] = fh->_covmat(1,1); cov[7] = fh->_covmat(2,1); + cov[2] = fh->_covmat(0,2); cov[5] = fh->_covmat(1,2); cov[8] = fh->_covmat(2,2); - // Fit failed beyond use - if ( gtr.mTrack == nullptr ){ - gtr.Clear(); - LOG_DEBUG << "GenfitTrack is nullptr, making StFwdTrack with seed info only" << endm; - return fwdTrack; + StFwdTrackSeedPoint p( StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), fh->getSector(), fh->getTrackId(), cov ); + fwdTrack->mFSTPoints.push_back( p ); + nSeedPoints++; } - // Fill charge and quality info - fwdTrack->setDidFitConverge( gtr.mStatus->isFitConverged() ); - fwdTrack->setDidFitConvergeFully( gtr.mStatus->isFitConvergedFully() ); - fwdTrack->setNumberOfFailedPoints( gtr.mStatus->getNFailedPoints() ); - fwdTrack->setNumberOfFitPoints( gtr.mTrack->getNumPoints() ); - fwdTrack->setChi2( gtr.mStatus->getChi2() ); - fwdTrack->setNDF( gtr.mStatus->getNdf() ); - fwdTrack->setPval( gtr.mStatus->getPVal() ); - - // charge at first point - fwdTrack->setCharge( gtr.mCharge ); - fwdTrack->setDCA( gtr.mDCA.X(), gtr.mDCA.Y(), gtr.mDCA.Z() ); - - TVector3 p = gtr.mMomentum;//cr->getMom( gtr.mTrack->getFittedState( 0, cr )); - fwdTrack->setPrimaryMomentum( StThreeVectorD( gtr.mMomentum.X(), gtr.mMomentum.Y(), gtr.mMomentum.Z() ) ); + // set total number of seed points + fwdTrack->setNumberOfSeedPoints( nSeedPoints ); - if ( gtr.isPrimary ){ - fwdTrack->setVtxIndex( 0 ); - } else { - fwdTrack->setVtxIndex( UCHAR_MAX ); - } + // compute projections to z-planes of various detectors + vector zPlanes = { + 0, // PV TODO, update with event vertex? + 151.750000, 165.248001, 178.781006, // FST + 280.904999, 303.704987, 326.605011, 349.404999, // FTT + 375.0, // EPD + 715.0, //ECAL + 807.0 // HCAL + }; + + // Note: as discussed, after verification storage of the projections + // @ the FST and FTT may no longer be needed, not saved in e.g. MuDst - /*******************************************************************************/ - // if the track is not (at least partially) converged, do not try to project it - if ( !gtr.mStatus->isFitConvergedPartially() ){ - gtr.Clear(); - return fwdTrack; - } + // this should always be the case, but being careful + if (gGeoManager) { + FwdGeomUtils fwdGeoUtils( gGeoManager ); + + // get the z-locations from geometry model and fallback to the defaults + auto fstZ = fwdGeoUtils.fstZ( {151.750000, 165.248001, 178.781006} ); + auto fttZ = fwdGeoUtils.fttZ( {280.904999, 303.704987, 326.605011, 349.404999} ); - /*******************************************************************************/ - // compute projections to z-planes of various detectors - // TODO: update FCS to use correct z + angle - map mapDetectorToZPlane = { - { kTpcId, 0.0 }, - { kFstId, mFstZFromGeom[0] }, - { kFstId, mFstZFromGeom[1] }, - { kFstId, mFstZFromGeom[2] }, - { kFttId, mFttZFromGeom[0] }, - { kFttId, mFttZFromGeom[1] }, - { kFttId, mFttZFromGeom[2] }, - { kFttId, mFttZFromGeom[3] }, - { kFcsPresId, 375.0 }, - { kFcsWcalId, 715.0 }, - { kFcsHcalId, 807.0 } + // copy new values into the zPlanes vector + std::copy( fstZ.begin(), fstZ.end(), zPlanes.begin()+1 ); + std::copy( fttZ.begin(), fttZ.end(), zPlanes.begin()+4 ); + } + + // Match these to the z-planes above + const int FST = kFstId; + const int FTT = kFttId; + vector detMap = { + kTpcId, + FST, FST, FST, + FTT, FTT, FTT, FTT, + kFcsPresId, + kFcsWcalId, + kFcsHcalId }; size_t zIndex = 0; - TVector3 mom(0, 0, 0); - float cov[9]; - TVector3 tv3(0, 0, 0); - for ( auto zp : mapDetectorToZPlane ){ - int detIndex = zp.first; - float z = zp.second; - tv3.SetXYZ(0, 0, 0); - if ( detIndex != kFcsHcalId && detIndex != kFcsWcalId ){ - tv3 = ObjExporter::trackPosition( gtr.mTrack.get(), z, cov, mom ); + int detIndex = 0; + for ( float z : zPlanes ){ + detIndex = detMap[ zIndex]; + // LOG_DEBUG << "Calculating Projection for detId=" << detIndex << " @ z=" << z << endm; + TVector3 mom(0, 0, 0); + float cov[9]; + + TVector3 tv3(0, 0, 0); + if ( detIndex != kFcsHcalId ){ + tv3 = ObjExporter::trackPosition( track, z, cov, mom ); } else { // use a straight line projection to HCAL since GenFit cannot handle long projections - tv3 = ObjExporter::projectAsStraightLine( gtr.mTrack.get(), 575.0, 625.0, z, cov, mom ); + tv3 = ObjExporter::projectAsStraightLine( track, 575.0, 625.0, z, cov, mom ); } fwdTrack->mProjections.push_back( StFwdTrackProjection( detIndex, StThreeVectorF( tv3.X(), tv3.Y(), tv3.Z() ), StThreeVectorF( mom.X(), mom.Y(), mom.Z() ), cov) ); + + // // Add Proj info to TTree + mTreeData.tprojX.push_back( tv3.X() ); + mTreeData.tprojY.push_back( tv3.Y() ); + mTreeData.tprojZ.push_back( tv3.Z() ); + mTreeData.tprojIdD.push_back( detIndex ); + mTreeData.tprojIdT.push_back( indexTrack ); + zIndex++; } - /*******************************************************************************/ - /*******************************************************************************/ - // clear the GenfitTrackResult - gtr.Clear(); - - // return the StFwdTrack we made - return fwdTrack; + return fwdTrack; } void StFwdTrackMaker::FillEvent() { + LOG_DEBUG << "StFwdTrackMaker::FillEvent()" << endm; + // Now fill StEvent StEvent *stEvent = static_cast(GetInputDS("StEvent")); - if (!stEvent) - return; + + // FillEvent(); StFwdTrackCollection * ftc = stEvent->fwdTrackCollection(); if ( !ftc ){ LOG_INFO << "Creating the StFwdTrackCollection" << endm; @@ -1332,34 +1344,57 @@ void StFwdTrackMaker::FillEvent() { stEvent->setFwdTrackCollection( ftc ); } - size_t indexTrack = 0; + mTreeData.tprojN = 0; + mTreeData.tprojX.clear(); + mTreeData.tprojY.clear(); + mTreeData.tprojZ.clear(); + mTreeData.tprojIdD.clear(); + mTreeData.tprojIdT.clear(); + size_t indexTrack = 0; for ( auto gtr : mForwardTracker->getTrackResults() ) { - StFwdTrack* fwdTrack = makeStFwdTrack( gtr, indexTrack ); - indexTrack++; - if (nullptr == fwdTrack) - continue; - ftc->addTrack( fwdTrack ); + StFwdTrack* fwdTrack = makeStFwdTrack( gtr, indexTrack ); + if (nullptr == fwdTrack) + continue; + ftc->addTrack( fwdTrack ); } - LOG_INFO << "StFwdTrackCollection has " << ftc->numberOfTracks() << " tracks now" << endm; - - // Pico Dst requires a primary vertex, - // if we have a PicoDst maker in the chain, we need to add a primary vertex - // when one does not exist to get a "FWD" picoDst - auto mk = GetMaker("PicoDst"); - if ( mk && stEvent->numberOfPrimaryVertices() == 0 ){ - LOG_INFO << "Adding a primary vertex to StEvent since PicoDst maker was found in chain, but no vertices found" << endm; - stEvent->addPrimaryVertex( new StPrimaryVertex() ); - LOG_INFO << "StPrimaryVertex::numberOfPrimaryVertices = " << stEvent->numberOfPrimaryVertices() << endm; - } - // ProcessFwdTracks(); + mTreeData.tprojN = mTreeData.tprojX.size(); + LOG_DEBUG << "StFwdTrackCollection has " << ftc->numberOfTracks() << " tracks now" << endm; + ProcessFwdTracks(); } +void StFwdTrackMaker::FillTrackDeltas(){ + LOG_DEBUG << "Filling Track Deltas for Alignment" << endm; + const auto &fittedTracks = mForwardTracker -> getTrackResults(); + + for ( size_t i = 0; i < fittedTracks.size(); i++ ){ + auto st = fittedTracks[i].trackSeed; + auto gt = fittedTracks[i].track; + + if (fittedTracks[i].isFitConvergedFully == false){ + LOG_DEBUG << "Skipping track, failed fit" << endm; + continue; + } + + for ( KiTrack::IHit * hit : st ){ + TVector3 htv3(hit->getX(), hit->getY(), hit->getZ()); + + auto ttv3 = ObjExporter::trackPosition( gt, htv3.Z() ); + + mTreeData.thdX.push_back( (ttv3.X() - htv3.X()) ); + mTreeData.thdY.push_back( (ttv3.Y() - htv3.Y()) ); + mTreeData.thaX.push_back( htv3.X() ); + mTreeData.thaY.push_back( htv3.Y() ); + mTreeData.thaZ.push_back( htv3.Z() ); + mTreeData.thdN++; + } + } +} //FillTrackDeltas + void StFwdTrackMaker::FitVertex(){ - vector genfitTracks; + const auto &genfitTracks = mForwardTracker -> globalTracks(); - const auto &trackResults = mForwardTracker -> getTrackResults(); if ( genfitTracks.size() >= 2 ){ genfit::GFRaveVertexFactory gfrvf; @@ -1369,34 +1404,281 @@ void StFwdTrackMaker::FitVertex(){ bscm(1, 1) = bssXY*bssXY; bscm(2, 2) = 50.5 * 50.5; gfrvf.setBeamspot( TVector3( 0, 0, 0 ), bscm ); - + // std::vector< genfit::GFRaveVertex * > vertices; + const auto &genfitTracks = mForwardTracker -> globalTracks(); mRaveVertices.clear(); gfrvf.findVertices( &mRaveVertices, genfitTracks, false ); - + LOG_DEBUG << "mRaveVertices.size() = " << mRaveVertices.size() << endm; + for ( auto vert : mRaveVertices ){ LOG_DEBUG << TString::Format( "RAVE vertex @(%f, %f, %f)\n\n", vert->getPos().X(), vert->getPos().Y(), vert->getPos().Z() ) << endm; } } -} // FitVertex +} + +void StFwdTrackMaker::FillTTree(){ + + St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); + if (mGenTree) { + + // VERTICES + if ( g2t_vertex ){ + mTreeData.vmcN = g2t_vertex->GetNRows(); + if ( (unsigned)mTreeData.vmcN >= MAX_TREE_ELEMENTS ) mTreeData.vmcN = MAX_TREE_ELEMENTS; + LOG_INFO << "Saving " << mTreeData.vmcN << " vertices in TTree" << endm; + for ( int i = 0; i < mTreeData.vmcN; i++ ){ + g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(i); + mTreeData.vmcX.push_back( vert->ge_x[0] ); + mTreeData.vmcY.push_back( vert->ge_x[1] ); + mTreeData.vmcZ.push_back( vert->ge_x[2] ); + } + } + + // RAVE RECO VERTICES + mTreeData.vrcN = mRaveVertices.size(); + if ( (unsigned)mTreeData.vrcN >= MAX_TREE_ELEMENTS ) mTreeData.vrcN = MAX_TREE_ELEMENTS; + LOG_INFO << "Saving " << mTreeData.vrcN << " RAVE vertices in TTree" << endm; + for ( int i = 0; i < mTreeData.vrcN; i++ ) { + auto vert = mRaveVertices[i]; + mTreeData.vrcX.push_back( vert->getPos().X() ); + mTreeData.vrcY.push_back( vert->getPos().Y() ); + mTreeData.vrcZ.push_back( vert->getPos().Z() ); + } + + + + + if (mForwardTracker->getSaveCriteriaValues() && mTreeData.saveCrit ) { + for (auto crit : mForwardTracker->getTwoHitCriteria()) { + string name = crit->getName(); + + // special, save all hit info for this one + + + if ( name == "Crit2_BDT" ){ + mTreeData.Crits["Crit2_BDT_DeltaPhi"].clear(); + mTreeData.Crits["Crit2_BDT_DeltaRho"].clear(); + mTreeData.Crits["Crit2_BDT_RZRatio"].clear(); + mTreeData.Crits["Crit2_BDT_StraightTrackRatio"].clear(); + + for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { + mTreeData.Crits["Crit2_BDT_DeltaPhi"].push_back( kv["Crit2_BDT_DeltaPhi"] ); + mTreeData.Crits["Crit2_BDT_DeltaRho"].push_back( kv["Crit2_BDT_DeltaRho"] ); + mTreeData.Crits["Crit2_BDT_RZRatio"].push_back( kv["Crit2_BDT_RZRatio"] ); + mTreeData.Crits["Crit2_BDT_StraightTrackRatio"].push_back( kv["Crit2_BDT_StraightTrackRatio"] ); + } + + } + + if ( name == "Crit2_RZRatio" ){ + LOG_INFO << "allValues.size() = " << mForwardTracker->getCriteriaAllValues(name).size() << " == " << mForwardTracker->getCriteriaTrackIds(name).size() << endm; + assert( mForwardTracker->getCriteriaAllValues(name).size() == mForwardTracker->getCriteriaTrackIds(name).size() && " Crit lengths must be equal" ); + mTreeData.Crits["Crit2_RZRatio_x1"].clear(); + mTreeData.Crits["Crit2_RZRatio_y1"].clear(); + mTreeData.Crits["Crit2_RZRatio_z1"].clear(); + mTreeData.Crits["Crit2_RZRatio_x2"].clear(); + mTreeData.Crits["Crit2_RZRatio_y2"].clear(); + mTreeData.Crits["Crit2_RZRatio_z2"].clear(); + + mTreeData.CritTrackIds["Crit2_RZRatio_h1"].clear(); + mTreeData.CritTrackIds["Crit2_RZRatio_h2"].clear(); + mTreeData.CritTrackIds["Crit2_RZRatio_h3"].clear(); + + + for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { + mTreeData.Crits["Crit2_RZRatio_x1"].push_back( kv["Crit2_RZRatio_x1"] ); + mTreeData.Crits["Crit2_RZRatio_y1"].push_back( kv["Crit2_RZRatio_y1"] ); + mTreeData.Crits["Crit2_RZRatio_z1"].push_back( kv["Crit2_RZRatio_z1"] ); + + mTreeData.Crits["Crit2_RZRatio_x2"].push_back( kv["Crit2_RZRatio_x2"] ); + mTreeData.Crits["Crit2_RZRatio_y2"].push_back( kv["Crit2_RZRatio_y2"] ); + mTreeData.Crits["Crit2_RZRatio_z2"].push_back( kv["Crit2_RZRatio_z2"] ); + + mTreeData.CritTrackIds["Crit2_RZRatio_h1"].push_back( kv["Crit2_RZRatio_h1"] ); + mTreeData.CritTrackIds["Crit2_RZRatio_h2"].push_back( kv["Crit2_RZRatio_h2"] ); + mTreeData.CritTrackIds["Crit2_RZRatio_h3"].push_back( -1 ); + } + } + + + LOG_DEBUG << "Saving Criteria values from " << name << " in TTree" << endm; + mTreeData.Crits[name].clear(); + mTreeData.CritTrackIds[name].clear(); + // copy by value so ROOT doesnt get lost (uses pointer to vector) + for (float v : mForwardTracker->getCriteriaValues(name)) { + mTreeData.Crits[name].push_back(v); + } + for (int v : mForwardTracker->getCriteriaTrackIds(name)) { + mTreeData.CritTrackIds[name].push_back(v); + } + } + + // three hit criteria + for (auto crit : mForwardTracker->getThreeHitCriteria()) { + string name = crit->getName(); + + // special, save all hit info for this one + if ( name == "Crit2_RZRatio" ){ + LOG_INFO << "allValues.size() = " << mForwardTracker->getCriteriaAllValues(name).size() << " == " << mForwardTracker->getCriteriaTrackIds(name).size() << endm; + assert( mForwardTracker->getCriteriaAllValues(name).size() == mForwardTracker->getCriteriaTrackIds(name).size() && " Crit lengths must be equal" ); + + mTreeData.CritTrackIds["Crit2_RZRatio_h1"].clear(); + mTreeData.CritTrackIds["Crit2_RZRatio_h2"].clear(); + mTreeData.CritTrackIds["Crit2_RZRatio_h3"].clear(); + + for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { + mTreeData.CritTrackIds["Crit2_RZRatio_h1"].push_back( kv["Crit2_RZRatio_h1"] ); + mTreeData.CritTrackIds["Crit2_RZRatio_h2"].push_back( kv["Crit2_RZRatio_h2"] ); + mTreeData.CritTrackIds["Crit2_RZRatio_h3"].push_back( kv["Crit2_RZRatio_h3"] ); + } + } + + + LOG_DEBUG << "Saving Criteria values from " << name << " in TTree" << endm; + mTreeData.Crits[name].clear(); + mTreeData.CritTrackIds[name].clear(); + // copy by value so ROOT doesnt get lost (uses pointer to vector) + for (float v : mForwardTracker->getCriteriaValues(name)) { + mTreeData.Crits[name].push_back(v); + } + for (int v : mForwardTracker->getCriteriaTrackIds(name)) { + mTreeData.CritTrackIds[name].push_back(v); + } + } + + // clear them + mForwardTracker->clearSavedCriteriaValues(); + } + + // SAVE RECO tracks + + mTreeData.rcN = 0; + const auto &fittedTracks = mForwardTracker -> getTrackResults(); + + LOG_INFO << "There are " << fittedTracks.size() << " seed tracks to save" << endm; + size_t maxToSave = fittedTracks.size(); + if (maxToSave >= 200) { + maxToSave = 0; + LOG_INFO << "More than 200 tracks , not saving unfit tracks" << endm; + } + + for ( size_t i = 0; i < maxToSave; i++ ){ + if ( i >= MAX_TREE_ELEMENTS ){ + LOG_WARN << "Truncating Reco tracks in TTree output" << endm; + break; + } + + int idt = 0; + double qual = 0; + idt = MCTruthUtils::dominantContribution(fittedTracks[i].trackSeed, qual); + + if ( fittedTracks[i].track == nullptr || fittedTracks[i].trackRep == nullptr ) { + LOG_INFO << "Skip saving null track" << endm; + continue; + } + + if ( fittedTracks[i].isFitConverged == false ){ + LOG_INFO << "Skip saving track where fit did not converge" << endm; + continue; + } + + + mTreeData.rcQuality.push_back( qual ); + mTreeData.rcTrackId.push_back( idt ); + + mTreeData.rcCharge.push_back( fittedTracks[i].charge ); + mTreeData.rcPt.push_back( fittedTracks[i].momentum.Pt() ); + mTreeData.rcEta.push_back( fittedTracks[i].momentum.Eta() ); + mTreeData.rcPhi.push_back( fittedTracks[i].momentum.Phi() ); + + mTreeData.rcNumPV.push_back( fittedTracks[i].nPV ); + mTreeData.rcNumFTT.push_back( fittedTracks[i].nFTT ); + mTreeData.rcNumFST.push_back( fittedTracks[i].nFST ); + + mTreeData.rcN ++; + } + LOG_INFO << "Filling TTree" << endm; + mTree->Fill(); + } // if mGenTree +} + //________________________________________________________________________ void StFwdTrackMaker::Clear(const Option_t *opts) { LOG_DEBUG << "StFwdTrackMaker::CLEAR" << endm; mForwardData->clear(); - mForwardTracker->Clear(); - - // clear fwd hits from fst and ftt - mFwdHitsFst.clear(); - mFwdHitsFtt.clear(); - - // clear vectors for visualization OBJ hits - mFttHits.clear(); - mFstHits.clear(); - mFcsPreHits.clear(); - mFcsClusters.clear(); - mFwdTracks.clear(); + if (mGenTree){ + mTreeData.thdN = mTreeData.fttN = mTreeData.rcN = mTreeData.mcN = mTreeData.vmcN = mTreeData.vrcN = mTreeData.fcsN = 0; + mTreeData.fttX.clear(); + mTreeData.fttY.clear(); + mTreeData.fttZ.clear(); + mTreeData.fttTrackId.clear(); + mTreeData.fttVolumeId.clear(); + mTreeData.fttPt.clear(); + mTreeData.fttVertexId.clear(); + + mTreeData.fstX.clear(); + mTreeData.fstY.clear(); + mTreeData.fstZ.clear(); + mTreeData.fstTrackId.clear(); + + mTreeData.fcsX.clear(); + mTreeData.fcsY.clear(); + mTreeData.fcsZ.clear(); + mTreeData.fcsDet.clear(); + + mTreeData.rcPt.clear(); + mTreeData.rcEta.clear(); + mTreeData.rcPhi.clear(); + mTreeData.rcQuality.clear(); + mTreeData.rcTrackId.clear(); + mTreeData.rcNumFST.clear(); + mTreeData.rcCharge.clear(); + mTreeData.rcNumFTT.clear(); + mTreeData.rcNumPV.clear(); + + + mTreeData.mcPt.clear(); + mTreeData.mcEta.clear(); + mTreeData.mcPhi.clear(); + mTreeData.mcVertexId.clear(); + mTreeData.mcCharge.clear(); + mTreeData.vmcX.clear(); + mTreeData.vmcY.clear(); + mTreeData.vmcZ.clear(); + + mTreeData.tprojX.clear(); + mTreeData.tprojY.clear(); + mTreeData.tprojZ.clear(); + mTreeData.tprojPx.clear(); + mTreeData.tprojPy.clear(); + mTreeData.tprojPz.clear(); + mTreeData.vrcX.clear(); + mTreeData.vrcY.clear(); + mTreeData.vrcZ.clear(); + mTreeData.thdX.clear(); + mTreeData.thdY.clear(); + mTreeData.thaX.clear(); + mTreeData.thaY.clear(); + mTreeData.thaZ.clear(); + + mTreeData.thdX.clear(); + mTreeData.thdY.clear(); + mTreeData.thaX.clear(); + mTreeData.thaY.clear(); + mTreeData.thaZ.clear(); + + mTreeData.fttN = 0; + mTreeData.fstN = 0; + mTreeData.rcN = 0; + mTreeData.mcN = 0; + mTreeData.vmcN = 0; + mTreeData.tprojN = 0; + mTreeData.vrcN = 0; + mTreeData.thdN = 0; + } } //________________________________________________________________________ void StFwdTrackMaker::ProcessFwdTracks( ){ @@ -1417,7 +1699,9 @@ std::string StFwdTrackMaker::defaultConfigIdealSim = R"( - + + + @@ -1431,49 +1715,39 @@ std::string StFwdTrackMaker::defaultConfigData = R"( - + - + - - - - + + + + - + - - + - + 0.99 0.001 - + - - - + + + -)"; - - -const std::vector &StFwdTrackMaker::getTrackSeeds() const{ - return mForwardTracker->getTrackSeeds(); -} - -const std::vector &StFwdTrackMaker::getFitResults()const{ - return mForwardTracker->getTrackResults(); -} +)"; \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/StFwdTrackMaker.h b/StRoot/StFwdTrackMaker/StFwdTrackMaker.h index 819b3ed0934..e04c158bb45 100644 --- a/StRoot/StFwdTrackMaker/StFwdTrackMaker.h +++ b/StRoot/StFwdTrackMaker/StFwdTrackMaker.h @@ -5,12 +5,10 @@ #ifndef __CINT__ #include "GenFit/Track.h" -#include "StFwdTrackMaker/include/Tracker/FwdHit.h" #endif #include "FwdTrackerConfig.h" #include "TVector3.h" -#include "TMatrix.h" namespace KiTrack { class IHit; @@ -40,10 +38,67 @@ class McTrack; // STL includes #include #include + + +// 877-369-6347 class StFwdTrack; class GenfitTrackResult; + +const size_t MAX_TREE_ELEMENTS = 4000; +struct FwdTreeData { + + // hits; + int fttN; + vector fttX, fttY, fttZ; + vector fttVolumeId; + // Only avalaible for hits if MC + vector fttPt; + vector fttTrackId, fttVertexId; + + // hits; + int fstN; + vector fstX, fstY, fstZ; + vector fstTrackId; + + int fcsN; + vector fcsX, fcsY, fcsZ; + vector fcsDet; + + // RC tracks + int rcN; + vector rcPt, rcEta, rcPhi, rcQuality; + vector rcTrackId, rcNumFST, rcCharge, rcNumFTT, rcNumPV; + + // MC Tracks + int mcN; + vector mcPt, mcEta, mcPhi; + vector mcVertexId, mcCharge; + + // MC Level vertex info + // maybe use also for TPC vertex if available in data + int vmcN; + vector vmcX, vmcY, vmcZ; + + int tprojN; + vector tprojX, tprojY, tprojZ; + vector tprojPx, tprojPy, tprojPz; + vector tprojIdD, tprojIdT; + + // RAVE reco vertices + int vrcN; + vector vrcX, vrcY, vrcZ; + + int thdN; + vector thdX, thdY, thaX, thaY, thaZ; + + bool saveCrit = false; + std::map> Crits; + std::map> CritTrackIds; + +}; + class StFwdTrackMaker : public StMaker { ClassDef(StFwdTrackMaker, 0); @@ -65,41 +120,34 @@ class StFwdTrackMaker : public StMaker { LoadConfiguration(); } void LoadConfiguration(); + void SetGenerateHistograms( bool _genHisto ){ mGenHistograms = _genHisto; } + void SetGenerateTree(bool _genTree) { mGenTree = _genTree; } void SetVisualize( bool _viz ) { mVisualize = _viz; } vector mFwdTracks; - vector &GetFttHits() { return mFwdHitsFtt; } - vector &GetFstHits() { return mFwdHitsFst; } - - #ifndef __CINT__ - // Get the FwdTracker object - std::shared_ptr GetForwardTracker() { return mForwardTracker; } - const std::vector &getTrackSeeds() const; - const std::vector &getFitResults() const; - #endif - TVector3 GetEventPrimaryVertex(); - private: protected: - // Event Filters - float mEventFilterMinTofMult = 2; - bool mEventFilterRequireEventVertex = false; - bool mEventFilterRequireVpdVertex = true; - float mEventFilterMinVpdZ = -99; - float mEventFilterMaxVpdZ = 99; + // Track Seed typdef + typedef std::vector Seed_t; + // for Wavefront OBJ export - size_t eventIndex = 0; // counts up for processed events - size_t mEventNum = 0; // global event num (index) - TVector3 mEventVertex; // primary vertex used in fwd tracking this event + size_t eventIndex = 0; + + bool mGenHistograms = false; + bool mGenTree = false; std::string mConfigFile; + std::map mHistograms; + TFile *mTreeFile = nullptr; + TTree *mTree = nullptr; + FwdTreeData mTreeData; - bool mVisualize = false; // if true,write out a Wavefront OBJ to visualize the event in 3D + bool mVisualize = false; vector mFttHits; vector mFstHits; vector mFcsClusters; @@ -107,193 +155,175 @@ class StFwdTrackMaker : public StMaker { vector mFcsPreHits; std::vector< genfit::GFRaveVertex * > mRaveVertices; - vector mFttZFromGeom, mFstZFromGeom; void ProcessFwdTracks(); void FillEvent(); void FillTrackDeltas(); - bool SkipEvent(); StFwdTrack * makeStFwdTrack( GenfitTrackResult >r, size_t indexTrack ); // I could not get the library generation to succeed with these. // so I have removed them #ifndef __CINT__ - TMatrixDSym mEventVertexCov; // covariance matrix for the primary vertex - enum FwdVertexSource { kFwdVertexSourceUnknown, kFwdVertexSourceNone, kFwdVertexSourceTpc, kFwdVertexSourceMc, kFwdVertexSourceVpd }; // unknown means we havent looked yet - FwdVertexSource mFwdVertexSource = StFwdTrackMaker::kFwdVertexSourceUnknown; - vector mFwdHitsFtt; - vector mFwdHitsFst; std::shared_ptr mSiRasterizer; FwdTrackerConfig mFwdConfig; std::shared_ptr mForwardTracker; std::shared_ptr mForwardData; + size_t loadMcTracks( std::map> &mcTrackMap ); void loadFcs(); void loadFttHits( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); void loadFttHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); void loadFttHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); - int loadFstHits( std::map> &mcTrackMap, std::map> &hitMap ); - int loadFstHitsFromMuDst( std::map> &mcTrackMap, std::map> &hitMap ); - int loadFstHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap ); - int loadFstHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap ); - int loadFstHitsFromStRnDHits( std::map> &mcTrackMap, std::map> &hitMap ); + void loadFstHits( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); + void loadFstHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); + void loadFstHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); #endif - - /** @brief Fit the primary vertex using FWD tracks */ + void FillTTree(); // if debugging ttree is turned on (mGenTree) void FitVertex(); static std::string defaultConfigIdealSim; static std::string defaultConfigData; std::string defaultConfig; bool configLoaded = false; - TString mGeoCache; // Helper functions for modifying configuration // NOTE: to override configuration, call individual functions after setConfigForXXX public: - /** @brief Setup the StFwdTrackMaker for running on Data - * Load the default configuration for Data. + /**@brief Setup the StFwdTrackMaker for running on Data + * Load the default configuration for Data. * Note: Apply any overrides after calling this */ void setConfigForData() { defaultConfig = defaultConfigData; LoadConfiguration(); } - /** @brief Setup the StFwdTrackMaker for running on Data + /**@brief Setup the StFwdTrackMaker for running on Data * Load the default configuration for IDEAL simulation. * This runs with MC track finding and MC-seeded track fitting. - * - MC track finding uses the MCTrackId to collect stgc/fst hits into track seeds + * - MC track finding uses the MCTrackId to collect stgc/fst hits into track seeds * - MC-seeded track fitting uses the MC particle momentum to seed the track fit * - Also uses the simulated MC primary vertex with smearing according to the simgaXY,Z * Note: Apply any overrides after calling this */ void setConfigForIdealSim() { defaultConfig = defaultConfigIdealSim; LoadConfiguration(); } - /** @brief Setup the StFwdTrackMaker for running on Data + /**@brief Setup the StFwdTrackMaker for running on Data * Load the default configuration for Realistic simulation. * This runs tracking on simulation using the same parameters / approach as on data. * Note: Apply any overrides after calling this */ - void setConfigForRealisticSim() { - defaultConfig = defaultConfigData; - LoadConfiguration(); + void setConfigForRealisticSim() { + defaultConfig = defaultConfigData; + LoadConfiguration(); // Note: Once the slow sims work this override will not be needed // because the slow sims will put hits into StEvent just like (data) reco chain setFttHitSource( "GEANT" ); } - /** @brief Set the filename for output ROOT file + /**@brief Set the filename for output ROOT file * @param fn : filename of output ROOT file */ void setOutputFilename( std::string fn ) { mFwdConfig.set( "Output:url", fn ); } - /** @brief Set the data source for FTT hits - * + /**@brief Set the data source for FTT hits + * * @param source : {DATA, GEANT}, DATA means read from StEvent, GEANT means read directly from the GEANT hits */ void setFttHitSource( std::string source ) { mFwdConfig.set( "Source:ftt", source ); } - - /** @brief Enable or disable the Fst Rasterizer + + /**@brief Enable or disable the Fst Rasterizer * @param use : if true, load FST hits from GEANT and raster them according to r, phi resolutions. */ void setUseFstRasteredGeantHits( bool use = true ){ mFwdConfig.set( "SiRasterizer:active", use ); } - /** @brief Set the resolution in R for rasterizing FST hits (from fast sim) + /**@brief Set the resolution in R for rasterizing FST hits (from fast sim) * Only used when the Rasterizer is enabled, which results from reading FST hits from GEANT * @param r : resolution in r (cm) */ void setFstRasterR( double r = 3.0 /*cm*/ ){ mFwdConfig.set( "SiRasterizer:r", r ); } - /** @brief Set the resolution in phi for rasterizing FST hits (from fast sim) + /**@brief Set the resolution in phi for rasterizing FST hits (from fast sim) * Only used when the Rasterizer is enabled, which results from reading FST hits from GEANT * @param phi : resolution in phi (rad) */ void setFstRasterPhi( double phi = 0.00409 /*2*pi/(12*128)*/ ){ mFwdConfig.set( "SiRasterizer:phi", phi ); } //Track Finding - /** @brief Use FST and Ftt hits (sequentially) in the Seed Finding - then merge tracks - * - */ - void setSeedFindingWithFstFttSequential() { mFwdConfig.set( "TrackFinder:source", "seq" ); } - /** @brief Use FST and Ftt hits (simultaneously) in the Seed Finding - * - */ - void setSeedFindingWithFstFttSimultaneous() { mFwdConfig.set( "TrackFinder:source", "sim" ); } - /** @brief Use Ftt hits in the Seed Finding - * + /**@brief Use Ftt hits in the Seed Finding + * */ void setSeedFindingWithFtt() { mFwdConfig.set( "TrackFinder:source", "ftt" ); } - /** @brief Use Fst hits in the Seed Finding - * + /**@brief Use Fst hits in the Seed Finding + * */ void setSeedFindingWithFst() { mFwdConfig.set( "TrackFinder:source", "fst" ); } - /** @brief Set the number of track finding iterations + /**@brief Set the number of track finding iterations * @param n : number of iterations to run */ void setSeedFindingNumInterations( int n = 1 ) { mFwdConfig.set("TrackFinder:nIterations", n); } - /** @brief Set the number of phi slices to split the track iterations into + /**@brief Set the number of phi slices to split the track iterations into * @param n : number of slices of equal size (2pi)/n */ void setSeedFindingNumPhiSlices( int n = 8 ) { mFwdConfig.set("TrackFinder.Iteration:nPhiSlices", n); } - /** @brief Set the connector distance for track finding + /**@brief Set the connector distance for track finding * @param d : distance between planes (1 = adjacent) */ void setSeedFindingConnectorDistance( int d = 1 ) { mFwdConfig.set( "TrackFinder.Connector:distance", d ); } - /** @brief Enable or disable the SubsetNN + /**@brief Enable or disable the SubsetNN * @param use : if true, enables the subsetNN which find the most compatible set of tracks without shared hits * if false, all tracks are reported regardless of shared hits */ void setSeedFindingUseSubsetNN( bool use = true ) { mFwdConfig.set( "TrackFinder.SubsetNN:active", use ); } - /** @brief Enable or disable the SubsetNN + /**@brief Enable or disable the SubsetNN * @param n : minimum number of hits on a track seed. Seeds with fewer hits are discarded */ void setSeedFindingMinHitsOnTrack( int n = 3 ) { mFwdConfig.set( "TrackFinder.SubsetNN:min-hits-on-track", n ); } - /** @brief Enable or disable the HitRemover + /**@brief Enable or disable the HitRemover * @param use : if true, enables the hit remover which removes any hits from the hitmap that were used in a track * if false, hits are not removed after each iteration */ void setSeedFindingUseHitRemover( bool use = true ) { mFwdConfig.set( "TrackFinder.HitRemover:active", use ); } - /** @brief Enable or disable the Truth Seed finding + /**@brief Enable or disable the Truth Seed finding * @param use : if true, use Mc info to group hits into track seeds * if false, seed finding uses options as in the case for data */ void setUseTruthSeedFinding( bool use = true ) { mFwdConfig.set( "TrackFinder:active", !use ); } // Track Fitting - /** @brief Turn off track fitting + /**@brief Turn off track fitting * Useful if you want to speed up the run but dont need fitting (testing seed finding) */ void setTrackFittingOff() { mFwdConfig.set( "TrackFitter:active", "false" ); } - /** @brief Enable / disable material effects + /**@brief Enable / disable material effects * Material effects in kalman filter */ void setFittingMaterialEffects( bool mat = true) { mFwdConfig.set( "TrackFitter:materialEffects", mat ); } - /** @brief Set the resolution for the Primary Vertex in XY + /**@brief Set the resolution for the Primary Vertex in XY * @params sXY : sigma in XY (cm) */ void setPrimaryVertexSigmaXY( double sXY ) { mFwdConfig.set( "TrackFitter.Vertex:sigmaXY", sXY ); } - /** @brief Set the resolution for the Primary Vertex in Z + /**@brief Set the resolution for the Primary Vertex in Z * @params sZ : sigma in Z (cm) */ void setPrimaryVertexSigmaZ( double sZ ) { mFwdConfig.set( "TrackFitter.Vertex:sigmaZ", sZ ); } // TODO: add options for beamline constraint - /** @brief Include or exclude the Primary Vertex in fit + /**@brief Include or exclude the Primary Vertex in fit * @param pvf : if true, use PRimary Vertex in fit */ void setIncludePrimaryVertexInFit( bool pvf = true ) { mFwdConfig.set( "TrackFitter.Vertex:includeInFit", pvf ); } - /** @brief Set B-field to zero (for zero field running) + /**@brief Set B-field to zero (for zero field running) * @param zeroB : if true, use Zero B field */ void setZeroB( bool zeroB = true ) { mFwdConfig.set( "TrackFitter:zeroB", zeroB ); } - /** @brief Set B-field to constant (even outside of TPC) + /**@brief Set B-field to constant (even outside of TPC) * @param constB : if true, use const 0.5T B field */ void setConstB( bool constB = true ) { mFwdConfig.set( "TrackFitter:constB", constB ); } - /** @brief Force the use of McSeed for fit + /**@brief Force the use of McSeed for fit * @param mcSeed : if true, use mc momentum as the seed for the track fitter */ void setUseMcSeedForFit( bool mcSeed = true ) { mFwdConfig.set( "TrackFitter:mcSeed", mcSeed ); } - /** @brief Sets the tracking to refit + /**@brief Sets the tracking to refit * This adds compatible hits from whichever detector was NOT used in seed finding * if FTT seeding -> project to and add FST hits * if FST seeding -> project to and add FTT hits @@ -301,81 +331,28 @@ class StFwdTrackMaker : public StMaker { */ void setTrackRefit( bool refit = true) { mFwdConfig.set( "TrackFitter:refit", refit ); } - /** @brief Sets the maximum number of hits that can be considered failed before the entire track fit fails + /**@brief Sets the maximum number of hits that can be considered failed before the entire track fit fails * @param n : number of failed hits allowed, -1 = no limit */ void setMaxFailedHitsInFit( int n = -1 /*no lim*/ ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MaxFailedHits", n);} - /** @brief Sets Fitter debug level + /**@brief Sets Fitter debug level * @param level : 0 = no output, higher numbers are more verbose */ void setFitDebugLvl( int level = 0 /*0=no output*/ ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:DebugLvl", level); } - /** @brief Sets Max fit iterations before failing + /**@brief Sets Max fit iterations before failing * @param n : num iterations */ void setFitMaxIterations( int n=4 ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MaxIterations", n); } - /** @brief Sets Min fit iterations before converging + /**@brief Sets Min fit iterations before converging * @param n : num iterations */ void setFitMinIterations( int n = 1) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MinIterations", n); } - /** @brief Enables smearing of the MC Primary Vertex according to sigmaXY,Z - * @param pvs : if true, smear vertex + /**@brief Enables smearing of the MC Primary Vertex according to sigmaXY,Z + * @param pvs : if true, smear vertex */ void setSmearMcPrimaryVertex( bool pvs = true ) { mFwdConfig.set( "TrackFitter.Vertex:smearMcVertex", pvs ); } - - /** - * @brief Sets geometry cache filename - * - */ - void setGeoCache( TString gc ) { mGeoCache = gc; } - - /** - * @brief Set a generic Key Value in the Config object - * - * @param k key: any string representing absolute path e.g. `the.path.to.node:attribute` - * @param v value: value encoded as a string - */ - void setConfigKeyValue( std::string k, std::string v ){ - mFwdConfig.set( k, v ); - } - - /** @brief Sets a criteria value in the config for 2-hit criteria - * @param string name: name of the crit2, e.g. Crit2_RZRatio - * @param double min: minimum for the criteria, meaning depends on specific crit2 - * @param double max: maximum for the criteria, meaning depends on specific crit2 - */ - void setCrit2( std::string name, double min, double max ){ - for ( auto p : mFwdConfig.childrenOf( "TrackFinder.Iteration.SegmentBuilder" ) ){ - auto nName = mFwdConfig.get( p + ":name", "DNE" ); - if (nName == name) { - LOG_DEBUG << "Setting Crit2=" << nName << " (min=" << min << ", max=" << max << ")" << endm; - mFwdConfig.set(p + ":min", min ); - mFwdConfig.set(p + ":max", max ); - return; - } - } // loop on existing crit2 - // if we got here then the crit did not exist - - } - - /** @brief Sets a criteria value in the config for 3-hit criteria - * @param string name: name of the crit3, e.g. Crit2_RZRatio - * @param double min: minimum for the criteria, meaning depends on specific crit2 - * @param double max: maximum for the criteria, meaning depends on specific crit2 - */ - void setCrit3( std::string name, double min, double max ){ - for ( auto p : mFwdConfig.childrenOf( "TrackFinder.Iteration.ThreeHitSegments" ) ){ - auto nName = mFwdConfig.get( p + ":name", "DNE" ); - if (nName == name) { - LOG_DEBUG << "Setting Crit3=" << nName << " (min=" << min << ", max=" << max << ")" << endm; - mFwdConfig.set(p + ":min", min ); - mFwdConfig.set(p + ":max", max ); - return; - } - } // loop on existing crit3 - // if we got here then the crit did not exist - } - + }; #endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h b/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h deleted file mode 100644 index bc608886d1b..00000000000 --- a/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef FITTERUTILS_H -#define FITTERUTILS_H - -#include "GenFit/KalmanFitter.h" -#include "GenFit/KalmanFitterInfo.h" -#include "GenFit/KalmanFitterRefTrack.h" -#include "GenFit/MaterialEffects.h" -#include "GenFit/PlanarMeasurement.h" -#include "GenFit/RKTrackRep.h" -#include "GenFit/SpacepointMeasurement.h" -#include "GenFit/StateOnPlane.h" -#include "GenFit/TGeoMaterialInterface.h" -#include "GenFit/Track.h" -#include "GenFit/TrackPoint.h" - -#include "TVector3.h" - - -class FitSeedMaker { - public: - FitSeedMaker() {} - virtual ~FitSeedMaker() {} - virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) = 0; -}; -class ConstFitSeeder : public FitSeedMaker { - public: - ConstFitSeeder() {} - virtual ~ConstFitSeeder() {} - virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) { - posSeed.SetXYZ(0,0,0); - momSeed.SetXYZ(0,0,10); - q = 1; - } -}; -class GenericFitSeeder : public FitSeedMaker { - public: - GenericFitSeeder() {} - virtual ~GenericFitSeeder() {} - // Simple function to calculate the determinant of a 2x2 matrix - inline double determinant(double a, double b, double c, double d) { - return a * d - b * c; - } - struct Point { - double x, y; - }; - // Function to compute the curvature of a circle given 3 points - double computeSignedCurvature(const Point& p1, const Point& p2, const Point& p3) { - // Calculate the lengths of the sides of the triangle - double A = std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2)); - double B = std::sqrt(std::pow(p3.x - p2.x, 2) + std::pow(p3.y - p2.y, 2)); - double C = std::sqrt(std::pow(p1.x - p3.x, 2) + std::pow(p1.y - p3.y, 2)); - - // Calculate the determinant of the matrix formed by the points - double det = determinant(p2.x - p1.x, p2.y - p1.y, p3.x - p1.x, p3.y - p1.y); - // LOG_INFO << "Det: " << det << endm; - double charge = det > 0 ? -1 : 1; - // Area of the triangle formed by the three points - double area = std::abs(det) / 2.0; - - if (area == 0) { - std::cerr << "The points are collinear, curvature is undefined." << std::endl; - return -1; // Curvature is undefined for collinear points - } - - // Calculate the radius of the circumcircle using the formula: - // R = (A * B * C) / (4 * area) - double radius = (A * B * C) / (4 * area); - // LOG_INFO << "Radius: " << radius << endm; - // Curvature is the inverse of the radius - return charge / radius; - } - // Function to compute the average curvature for all combinations of 3 points - double averageCurvature( const Seed_t points ) { - // const std::vector& points; - int numPoints = points.size(); - if (numPoints < 3) { - std::cerr << "Not enough points to form a circle." << std::endl; - return -1; - } - - double totalCurvature = 0.0; - int validCombinations = 0; - - // Iterate over all combinations of 3 points - for (int i = 0; i < numPoints - 2; ++i) { - for (int j = i + 1; j < numPoints - 1; ++j) { - for (int k = j + 1; k < numPoints; ++k) { - Point p0 = {points[i]->getX(), points[i]->getY()}; - Point p1 = {points[j]->getX(), points[j]->getY()}; - Point p2 = {points[k]->getX(), points[k]->getY()}; - double curvature = computeSignedCurvature(p0, p1, p2); - if (curvature != -1) { // Exclude invalid (collinear) combinations - totalCurvature += curvature; - ++validCombinations; - } - } - } - } - - if (validCombinations == 0) { - std::cerr << "No valid curvature calculations possible." << std::endl; - return -1; // No valid triangles were found - } - - return totalCurvature / validCombinations; - } - - template int sgn(T val) { - return (T(0) < val) - (val < T(0)); - } - virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) { - const double qc = averageCurvature(seed); - posSeed.SetXYZ(0,0,0); - momSeed.SetXYZ(0,0,10); - - const double BStrength = 0.5; // 0.5 T - const double C = 0.3 * BStrength; //C depends on the units used for momentum and Bfield (here GeV and Tesla) - const double K = 0.00029979; // K depends on the units used for Bfield and momentum (here Gauss and GeV) - double pt = fabs((K*5)/qc); // pT from average measured curv - - // set the momentum seed's transverse momentum - momSeed.SetPerp(pt); - // compute the seed's eta from seed points - TVector3 p0 = TVector3(seed[0]->getX(), seed[0]->getY(), seed[0]->getZ()); - TVector3 p1 = TVector3(seed[1]->getX(), seed[1]->getY(), seed[1]->getZ()); - double dx = (p1.X() - p0.X()); - double dy = (p1.Y() - p0.Y()); - double dz = (p1.Z() - p0.Z()); - double phi = TMath::ATan2(dy, dx); - double Rxy = sqrt(dx * dx + dy * dy); - double theta = TMath::ATan2(Rxy, dz); - if (abs(dx) < 1e-6 || abs(dy) < 1e-6){ - phi = TMath::ATan2( p1.Y(), p1.X() ); - } - - // momSeed.SetPhi(phi); - // momSeed.SetTheta(theta); - - // assign charge based on sign of curvature - q = sgn(qc); - } -}; - -#endif \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h index a94eeca9f4d..c26fabd95ae 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h @@ -32,11 +32,27 @@ class FwdDataSource { // Cleanup void clear() { - // Just empty our vectors, we dont own the memory - mFttHits.clear(); - mFstHits.clear(); - // the tracks are shared pointers, so they will be taken care of by clearing the map (below) - mMcTracks.clear(); + + // delete the hits from the hitmap + for ( auto kv : mFttHits ){ + for ( auto h : kv.second ){ + delete h; + } + kv.second.clear(); + } + + for ( auto kv : mFstHits ){ + for ( auto h : kv.second ){ + delete h; + } + kv.second.clear(); + } + + // the tracks are shared pointers, so they will be taken care of by clearing the map (below) + + mFttHits.clear(); + mFstHits.clear(); + mMcTracks.clear(); } // TODO, protect and add interaface for pushing hits / tracks diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h index 9d928fa7457..93e6de702b7 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h @@ -9,19 +9,13 @@ class FwdGeomUtils { public: - - FwdGeomUtils( TGeoManager * gMan ) { - if ( gMan != nullptr ){ + if ( gMan != nullptr ) _navigator = gMan->AddNavigator(); - _gMan = gMan; - } } ~FwdGeomUtils(){ - if ( _gMan != nullptr && _navigator != nullptr){ - _gMan->RemoveNavigator( _navigator ); - } + } bool cd( const char* path ){ @@ -49,11 +43,11 @@ class FwdGeomUtils { } double fttZ( int index ) { - // This ftt_z_delta is needed to match the z location of hits (midpint of active volume?) to the z location of the mother volume. + // This ftt_z_delta is needed to match the z location of hits (midpint of active volume?) to the z location of the mother volume. // NOTE: It may be possible to improve this when the higher precision FTT geometry model is added const double ftt_z_delta = -0.5825245; stringstream spath; - spath << "/HALL_1/CAVE_1/STGM_1/STFM_" << (index + 1) * 4 << "/"; + spath << "/HALL_1/CAVE_1/STGM_1/STFM_" << (index + 1) * 4 << "/"; bool can = cd( spath.str().c_str() ); if ( can && _matrix != nullptr ){ return _matrix->GetTranslation()[2] + ftt_z_delta; @@ -75,12 +69,12 @@ class FwdGeomUtils { // the index are now 4,5,6 // hence +4 below // also fixed typo, previously was incorrectly FTSD_ - const double z_delta = 1.755; + stringstream spath; - spath << "/HALL_1/CAVE_1/FSTM_1/FSTD_" << (index + 4) << "/"; + spath << "/HALL_1/CAVE_1/FSTM_1/FSTD_" << (index + 4) << "/"; bool can = cd( spath.str().c_str() ); if ( can && _matrix != nullptr ){ - return _matrix->GetTranslation()[2] + z_delta; + return _matrix->GetTranslation()[2]; } return 0.0; } @@ -91,7 +85,6 @@ class FwdGeomUtils { TGeoHMatrix *_matrix = nullptr; TGeoIterator *_iter = nullptr; TGeoNavigator *_navigator = nullptr; - TGeoManager *_gMan = nullptr; }; -#endif +#endif \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h index bc44ea71548..bcf4cb1fa7b 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h @@ -11,8 +11,6 @@ #include #include -#include "StEvent/StEnumerations.h" - class StHit; class FwdSystem : public KiTrack::ISectorSystem { @@ -22,7 +20,7 @@ class FwdSystem : public KiTrack::ISectorSystem { static const int sNFstLayers = 3; FwdSystem(const int ndisks = FwdSystem::sNFwdLayers) : KiTrack::ISectorSystem(), mNDisks(ndisks){}; ~FwdSystem(){/* */}; - virtual unsigned int getLayer(int diskid) const { + virtual unsigned int getLayer(int diskid) const throw(KiTrack::OutOfRange) { return diskid; } @@ -52,14 +50,14 @@ class McTrack { mStartVertex = start_vertex; } - void addFttHit(KiTrack::IHit *hit) { mFttHits.push_back(hit); } - void addFstHit(KiTrack::IHit *hit) { mFstHits.push_back(hit); } + void addHit(KiTrack::IHit *hit) { mHits.push_back(hit); } + // void addFstHit(KiTrack::IHit *hit) { mFstHits.push_back(hit); } double mPt, mEta, mPhi; int mTid, mQ, mStartVertex; - std::vector mFttHits; - std::vector mFstHits; + std::vector mHits; + // std::vector mFstHits; }; @@ -69,28 +67,13 @@ class McTrack { */ class FwdHit : public KiTrack::IHit { public: - // Default ctor - FwdHit() : KiTrack::IHit() { - _id = 0; - _x = 0; - _y = 0; - _z = 0; - _detid = 0; - _tid = 0; - _vid = 0; - _sector = 0; - _mcTrack = nullptr; - _hit = 0; - _covmat.ResizeTo( 3, 3 ); - }; - FwdHit(unsigned int id, float x, float y, float z, int vid, int detid, int tid, - TMatrixDSym covmat, std::shared_ptr mcTrack ) + FwdHit(unsigned int id, float x, float y, float z, int vid, int tid, + TMatrixDSym covmat, std::shared_ptr mcTrack = nullptr ) : KiTrack::IHit() { _id = id; _x = x; _y = y; _z = z; - _detid = detid; _tid = tid; _vid = vid; _mcTrack = mcTrack; @@ -111,29 +94,13 @@ class FwdHit : public KiTrack::IHit { } }; - // Set basic props for e.g. Primary Vertex type hits - void setXYZDetId( float x, float y, float z, int detid ){ - _x = x; - _y = y; - _z = z; - _detid = detid; - } - - bool isFst() const { return _detid == kFstId; } - bool isFtt() const { return _detid == kFttId; } - bool isPV() const { return _detid == kTpcId; } - - std::shared_ptr getMcTrack() { return _mcTrack; } - const KiTrack::ISectorSystem *getSectorSystem() const { return FwdSystem::sInstance; } - void setSector( int s ){ _sector = s; } int getTrackId() { return _tid;} int _tid; // aka ID truth int _vid; // volume id - int _detid; // detector id unsigned int _id; // just a unique id for each hit in this event. std::shared_ptr _mcTrack; TMatrixDSym _covmat; @@ -141,8 +108,7 @@ class FwdHit : public KiTrack::IHit { StHit *_hit; }; -// Track Seed typdef -typedef std::vector Seed_t; +using Seed_t = std::vector; class FwdConnector : public KiTrack::ISectorConnector { public: diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h index 531faf43eeb..1316f9eca61 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h @@ -10,18 +10,18 @@ #include "TRandom3.h" #include "TTree.h" #include "TVector3.h" -#include "TLorentzVector.h" #include #include #include #include #include -#include #include "StFwdTrackMaker/include/Tracker/FwdHit.h" #include "StFwdTrackMaker/include/Tracker/FwdDataSource.h" +#include "StFwdTrackMaker/include/Tracker/QualityPlotter.h" #include "StFwdTrackMaker/include/Tracker/TrackFitter.h" +#include "StFwdTrackMaker/include/Tracker/BDTCriteria.h" #include "Criteria/Criteria.h" #include "Criteria/ICriterion.h" @@ -41,7 +41,7 @@ struct MCTruthUtils { static int dominantContribution(Seed_t hits, double &qa) { - + // track_id, hits on track std::unordered_map truth; for ( auto hit : hits ) { @@ -49,10 +49,6 @@ struct MCTruthUtils { truth[ fhit->_tid ]++; } - if ( truth.size() == 0 ){ - return -1; - } - using namespace std; using P = decltype(truth)::value_type; auto dom = max_element(begin(truth), end(truth), [](P a, P b){ return a.second < b.second; }); @@ -61,222 +57,139 @@ struct MCTruthUtils { // vote the same way on the track if ( hits.size() > 0 ) qa = double(dom->second) / double(hits.size()) ; - else + else qa = 0; return dom->first; }; }; -class EventStats { - public: - TString classname() const { return "EventStats"; } - void reset(){ - mNumSeeds = 0; - mAttemptedFits = 0; - mFailedFits = 0; - mGoodFits = 0; - mGoodCardinals = 0; - - mAttemptedReFits = 0; - mFailedReFits = 0; - mGoodReFits = 0; - mPossibleReFit = 0; - - mNumFwdVertices = 0; - mAttemptedPrimaryFits = 0; - mGoodPrimaryFits = 0; - mFailedPrimaryFits = 0; - - mStep1Duration.clear(); - mStep2Duration.clear(); - mStep3Duration.clear(); - mStep4Duration.clear(); - mFitDuration.clear(); - } - int mNumSeeds = 0; - int mAttemptedFits = 0; - int mFailedFits = 0; - int mGoodFits = 0; - int mGoodCardinals = 0; - - int mAttemptedReFits = 0; - int mFailedReFits = 0; - int mGoodReFits = 0; - int mPossibleReFit = 0; - - int mNumFwdVertices = 0; - int mAttemptedPrimaryFits = 0; - int mGoodPrimaryFits = 0; - int mFailedPrimaryFits = 0; - vector mStep1Duration; - vector mSeedFindingDuration; - vector mStep2Duration; - vector mStep3Duration; - vector mStep4Duration; - vector mFitDuration; -}; - class GenfitTrackResult { public: - GenfitTrackResult(){} - GenfitTrackResult( Seed_t &seed, std::shared_ptr track ) { - set( seed, track ); - } - ~GenfitTrackResult(){ - // Clear(); - } - void Clear() { - if ( mTrack ){ - mTrack->Clear(); - } - } - void set( Seed_t &seeds, std::shared_ptr track ){ - setSeed( seeds ); - setTrack( track ); - } - void setSeed( Seed_t &seed ){ - mSeed = seed; - mIdTruth = MCTruthUtils::dominantContribution( seed, mQaTruth ); - LOG_INFO << "GenFitTrackResult::mIdTruth = " << mIdTruth << ", QaTruth = " << mQaTruth << endm; - } - void setTrack( std::shared_ptr track ){ + GenfitTrackResult( size_t nFTT, size_t nFST, + Seed_t &seedTrack, genfit::Track *track ) { + this->nFST = nFST; + this->nFTT = nFTT; + this->trackSeed = seedTrack; + try { - // this->track = new genfit::Track(*track); - mTrack = track; - mTrack ->setMcTrackId(mIdTruth); - mStatus = mTrack->getFitStatus(); - mTrackRep = mTrack->getCardinalRep(); - - mIsFitConverged = mStatus->isFitConverged(); - mIsFitConvergedFully = mStatus->isFitConvergedFully(); - mIsFitConvergedPartially = mStatus->isFitConvergedPartially(); - mNFailedPoints = mStatus->getNFailedPoints(); - mCharge = mStatus->getCharge(); - mChi2 = mStatus->getChi2(); - - if ( mIsFitConverged ){ - LOG_INFO << "GTR Setting momentum from track" << endm; - mMomentum = mTrackRep->getMom( mTrack->getFittedState(0, mTrackRep) ); - } + this->track = track; + this->status = *(this->track->getFitStatus()); + this->trackRep = this->track->getCardinalRep(); + + this->isFitConverged = this->status.isFitConverged(); + this->isFitConvergedFully = this->status.isFitConvergedFully(); + this->isFitConvergedPartially = this->status.isFitConvergedPartially(); + this->nFailedPoints = this->status.getNFailedPoints(); + this->charge = this->status.getCharge(); + + this->nPV = this->track->getNumPoints() - (nFTT + nFST); + + this->momentum = this->trackRep->getMom( this->track->getFittedState(0, this->trackRep) ); LOG_DEBUG << "GenfitTrackResult::set Track successful" << endm; + } catch ( genfit::Exception &e ) { - LOG_ERROR << "Unable to set track -> GenfitException: " << e.what() << endm; - this->mTrack = nullptr; - this->mTrackRep = nullptr; - - this->mIsFitConverged = false; - this->mIsFitConvergedFully = false; - this->mIsFitConvergedPartially = false; - this->mNFailedPoints = 99; - this->mCharge = 0; - this->mChi2 = -1; + LOG_ERROR << "GenfitTrackResult cannot get track" << endm; + this->track = nullptr; + this->trackRep = nullptr; + + this->isFitConverged = false; + this->isFitConvergedFully = false; + this->isFitConvergedPartially = false; + this->nFailedPoints = nFST + nFTT; + this->charge = 0; } } - /** @brief Set the DCA and primary vertex for the event - * - */ - void setDCA( TVector3 pv ){ - mPV = pv; - if ( mTrack ){ - try { - auto dcaState = mTrack->getFittedState( 0 ); - this->mTrackRep->extrapolateToPoint( dcaState, mPV ); - this->mDCA = dcaState.getPos(); - } catch ( genfit::Exception &e ) { - LOG_ERROR << "CANNOT GET DCA : GenfitException: " << e.what() << endm; - this->mDCA = TVector3(99,99,99); - } - - } - } - size_t numFtt() const { - size_t n = 0; - for ( auto hit : mSeed ){ - if ( dynamic_cast(hit)->_detid == kFttId ){ - n++; - } - } - return n; - } - size_t numFst() const { - size_t n = 0; - for ( auto hit : mSeed ){ - if ( dynamic_cast(hit)->_detid == kFstId ){ - n++; - } - } - return n; - } - size_t numPV() const { - size_t n = 0; - for ( auto hit : mSeed ){ - if ( dynamic_cast(hit)->isPV() ){ - n++; - } - } - return n; + ~GenfitTrackResult() { + // MEMORY LEAK + // LOG_INFO << "~GenfitTrackResult" << endm; + // if (this->track) + // delete this->track; + // this->track = nullptr; } - void mergeSeeds( GenfitTrackResult &other ){ - // combine the unique Ftt and Fst seeds - for ( auto hit : other.mSeed ){ - if ( std::find( mSeed.begin(), mSeed.end(), hit ) == mSeed.end() ){ - mSeed.push_back( hit ); - } + void setFst( Seed_t &seedFst, genfit::Track *track ){ + LOG_DEBUG << "GenfitTrackResult::setFSt" << endm; + nFST = seedFst.size(); + fstSeed = seedFst; + + try { + this->fstTrack = new genfit::Track(*track); + // make sure the McTrackId is set correctly + this->fstTrack->setMcTrackId( this->track->getMcTrackId() ); + this->fstStatus = *(this->fstTrack->getFitStatus()); + this->fstTrackRep = this->fstTrack->getCardinalRep(); + + this->isFitConverged = this->fstStatus.isFitConverged(); + this->isFitConvergedFully = this->fstStatus.isFitConvergedFully(); + this->isFitConvergedPartially = this->fstStatus.isFitConvergedPartially(); + this->nFailedPoints = this->fstStatus.getNFailedPoints(); + this->charge = this->fstStatus.getCharge(); + this->fstMomentum = this->fstTrackRep->getMom( this->fstTrack->getFittedState(0, this->fstTrackRep) ); + + } catch ( genfit::Exception &e ) { + LOG_ERROR << "CANNOT GET FST TRACK" << endm; + this->fstTrack = nullptr; + this->fstTrackRep = nullptr; + + this->fstIsFitConverged = false; + this->fstIsFitConvergedFully = false; + this->fstIsFitConvergedPartially = false; + this->fstNFailedPoints = nFST + nFTT; + this->fstCharge = 0; } } - bool isPrimary = false; - Seed_t mSeed; - TVector3 mPV; // as a TVector3 - TVector3 mMomentum; - float mCharge = 0; - float mChi2 = -1; - genfit::FitStatus *mStatus = nullptr; - genfit::AbsTrackRep *mTrackRep = nullptr; - std::shared_ptr mTrack = nullptr; - bool mIsFitConverged = false; - bool mIsFitConvergedFully = false; - bool mIsFitConvergedPartially = false; - size_t mNFailedPoints = 0; - TVector3 mDCA; - int mIdTruth = -1; - double mQaTruth = 0; -}; // GenfitTrackResult + Seed_t trackSeed; + Seed_t fstSeed; + TVector3 momentum; + double charge; + size_t nFST = 0; + size_t nFTT = 0; + size_t nPV = 0; + genfit::FitStatus status; + genfit::AbsTrackRep *trackRep = nullptr; + genfit::Track *track = nullptr; + bool isFitConverged = false; + bool isFitConvergedFully = false; + bool isFitConvergedPartially = false; + size_t nFailedPoints = 0; + + // Result after FST refit + genfit::Track *fstTrack = nullptr; + genfit::AbsTrackRep *fstTrackRep = nullptr; + genfit::FitStatus fstStatus; + bool fstIsFitConverged = false; + bool fstIsFitConvergedFully = false; + bool fstIsFitConvergedPartially = false; + size_t fstNFailedPoints = 0; + double fstCharge = 0; + TVector3 fstMomentum; + + void summary() { + LOG_INFO << TString::Format( "TrackResult[p=(%f, %f, %f)/(%f, %f, %f), q=%f, nFTT=%lu, nFST=%lu, nPV=%lu, isFitConvergedFully=%d]", momentum.X(), momentum.Y(), momentum.Z(), momentum.Pt(), momentum.Eta(), momentum.Phi(), charge, nFTT, nFST, nPV, isFitConvergedFully ).Data() << endm; + } +}; class ForwardTrackMaker { public: ForwardTrackMaker() : mConfigFile("config.xml"), mEventVertex(-999, -999, -999) { // noop } - + const std::vector &getTrackResults() const { return mTrackResults; } - const std::vector &getTrackSeeds() const { return mTrackSeeds; } - const EventStats &getEventStats() const { return mEventStats; } - - void Clear(){ - for ( auto gtr : mTrackResults ){ - gtr.Clear(); - } - mTrackResults.clear(); - } + const std::vector &getRecoTracks() const { return mRecoTracks; } + const std::vector &getFitMomenta() const { return mFitMoms; } + const std::vector &getNumFstHits() const { return mNumFstHits; } + const std::vector &getFitStatus() const { return mFitStatus; } + const std::vector &globalTrackReps() const { return mGlobalTrackReps; } + const std::vector &globalTracks() const { return mGlobalTracks; } - /** - * @brief Set the Config File object - * - * @param cf : config filename - */ void setConfigFile(std::string cf) { mConfigFile = cf; } - /** - * @brief Set the Save Criteria Values object - * - * @param save : true to save crit values - */ void setSaveCriteriaValues(bool save) { mSaveCriteriaValues = save; } @@ -286,26 +199,44 @@ class ForwardTrackMaker { // Adopt external hit loader void setData(std::shared_ptrdata) { mDataSource = data; } - /** - * @brief Initialize FwdTracker - * - * @param geoCache : name of cached geometry file - * @param genHistograms : generate histograms - */ virtual void initialize( TString geoCache, bool genHistograms) { + mGenHistograms = genHistograms; + if (mGenHistograms) setupHistograms(); + mGeoCache = geoCache; - mDoTrackFitting = mConfig.get("TrackFitter:active", true); + mDoTrackFitting = !(mConfig.get("TrackFitter:off", false)); if (!mConfig.exists("TrackFitter")) mDoTrackFitting = false; - } //initialize + } - /** - * @brief Loads Criteria from XML configuration. - * Utility function for loading criteria from XML config. - * @param path : path in config to load - * @return vector of ICriterion pointers - */ + + void writeEventHistograms() { + + // no file, dont write anything + if ( !gDirectory ) + return; + + gDirectory->cd(); + // write out the config we use (do before histos): + TNamed n("mConfig", mConfig.dump()); + n.Write(); + + writeHistograms(); + + gDirectory->mkdir("Fit/"); + gDirectory->cd("Fit/"); + mTrackFitter->writeHistograms(); + gDirectory->cd(""); + mQualityPlotter->writeHistograms(); + } + + /** Loads Criteria from XML configuration. + * + * Utility function for loading criteria from XML config. + * + * @return vector of ICriterion pointers + */ std::vector loadCriteria(string path) { std::vector crits; @@ -321,11 +252,10 @@ class ForwardTrackMaker { float vmin = mConfig.get(p + ":min", 0); float vmax = mConfig.get(p + ":max", 1); - + KiTrack::ICriterion * crit = nullptr; if ( name == "Crit2_BDT" ){ - // crit = new BDTCrit2( vmin, vmax ); - LOG_WARN << "BDT Criteria not implemented/out of date" << endm; + crit = new BDTCrit2( vmin, vmax ); } else { crit = KiTrack::Criteria::createCriterion(name, vmin, vmax); } @@ -336,32 +266,12 @@ class ForwardTrackMaker { crits.push_back(new CriteriaKeeper(crit)); // CriteriaKeeper intercepts values and saves them else crits.push_back(crit); - + } return crits; - } // loadCriteria - - /** - * @brief Clear the loaded criteria - * @param crits : vector of ICriterion pointers to properly clear - */ - void clearCriteria( std::vector &crits ){ - for ( size_t i = 0; i < crits.size(); i++ ){ - if ( crits[i] ){ - delete crits[i]; - crits[i] = nullptr; - } - } - crits.clear(); } - /** - * @brief Get the Criteria Values object - * - * @param crit_name : Criteria to get - * @return std::vector : list of values - */ std::vector getCriteriaValues(std::string crit_name) { std::vector em; if (mSaveCriteriaValues != true) { @@ -383,14 +293,8 @@ class ForwardTrackMaker { } return em; - } //getCriteriaValues + }; - /** - * @brief Get the Criteria All Values object - * - * @param crit_name : Criteria values to get - * @return std::vector> : map of values - */ std::vector> getCriteriaAllValues(std::string crit_name) { std::vector> em; if (mSaveCriteriaValues != true) { @@ -412,14 +316,8 @@ class ForwardTrackMaker { } return em; - } // getCriteriaAllValues + }; - /** - * @brief Get the Criteria Track Ids object - * - * @param crit_name : Name of criteria to get track ids for - * @return std::vector : list of track ids - */ std::vector getCriteriaTrackIds(std::string crit_name) { std::vector em; if (mSaveCriteriaValues != true) { @@ -441,12 +339,8 @@ class ForwardTrackMaker { } return em; - } //getCriteriaTrackIds + }; - /** - * @brief Clear the saved values for two hit and three hit criteria - * - */ void clearSavedCriteriaValues() { if (mSaveCriteriaValues != true) { return; @@ -461,28 +355,103 @@ class ForwardTrackMaker { auto critKeeper = static_cast(crit); critKeeper->clear(); } - } // clearSavedCriteria + } - /** - * @brief Determine the total num of hits in the hitmap - * - * @param hitmap : hitmap to consider - * @return size_t : total num of hits - */ size_t nHitsInHitMap(FwdDataSource::HitMap_t &hitmap) { size_t n = 0; + for (auto kv : hitmap) { n += kv.second.size(); } + return n; } - /** - * @brief Remove used hits from the hit map - * - * @param hitmap : hitmap with hits used this round - * @param tracks : tracks formed from hits - */ + size_t countRecoTracks(size_t nHits) { + size_t n = 0; + + for (auto t : mRecoTracks) { + if (t.size() == nHits) + n++; + } + + return n; + } + + void setupHistograms() { + + mHist["input_nhits"] = new TH1I("input_nhits", ";# hits", 1000, 0, 1000); + mHist["nAttemptedFits"] = new TH1I("nAttemptedFits", ";;# attempted fits", 10, 0, 10); + mHist["nPossibleFits"] = new TH1I("nPossibleFits", ";;# possible fits", 10, 0, 10); + // refit with silicon + mHist["nPossibleReFits"] = new TH1I("nPossibleReFits", ";;# possible REfits", 10, 0, 10); + mHist["nAttemptedReFits"] = new TH1I("nAttemptedReFits", ";;#attempted REfits", 10, 0, 10); + mHist["nFailedReFits"] = new TH1I("nFailedReFits", ";;# failed REfits", 10, 0, 10); + + mHist["FitStatus"] = new TH1I("FitStatus", ";;# failed REfits", 15, 0, 15); + FwdTrackerUtils::labelAxis(mHist["FitStatus"]->GetXaxis(), {"Seeds", "AttemptFit", "GoodFit", "BadFit", "GoodCardinal", "PossibleReFit", "AttemptReFit", "GoodReFit", "BadReFit", "w3Si","w2Si", "w1Si", "w0Si" }); + + mHist["FitDuration"] = new TH1I("FitDuration", ";Duration (ms)", 5000, 0, 50000); + mHist["nSiHitsFound"] = new TH2I( "nSiHitsFound", ";Si Disk; n Hits", 5, 0, 5, 10, 0, 10 ); + + mHist["Step1Duration"] = new TH1I("Step1Duration", ";Duration (ms)", 500, 0, 500); + mHist["Step2Duration"] = new TH1I("Step2Duration", ";Duration (ms)", 500, 0, 500); + mHist["Step3Duration"] = new TH1I("Step3Duration", ";Duration (ms)", 500, 0, 500); + mHist["Step4Duration"] = new TH1I("Step4Duration", ";Duration (ms)", 500, 0, 500); + } + + void fillHistograms() { + + if (mGenHistograms && mDataSource != nullptr) { + auto hm = mDataSource->getFttHits(); + for (auto hp : hm) + mHist["input_nhits"]->Fill(hp.second.size()); + } + } + + void writeHistograms() { + if ( !mGenHistograms ){ + return; + } + + for (auto nh : mHist) { + nh.second->SetDirectory(gDirectory); + nh.second->Write(); + } + } + + // this is the main event loop. doEvent processes a single event iEvent... + void make() { + + int single_event = mConfig.get("Input:event", -1); + + if (single_event >= 0) { + doEvent(single_event); + return; + } + + unsigned long long firstEvent = mConfig.get("Input:first-event", 0); + + if (mConfig.exists("Input:max-events")) { + unsigned long long maxEvents = mConfig.get("Input:max-events", 0); + + if (nEvents > maxEvents) + nEvents = maxEvents; + + } + + // loop over events + + for (unsigned long long iEvent = firstEvent; iEvent < firstEvent + nEvents; iEvent++) { + doEvent(iEvent); + } + + if (mGenHistograms){ + mQualityPlotter->finish(); + writeEventHistograms(); + } + } + void removeHits(FwdDataSource::HitMap_t &hitmap, std::vector &tracks) { for (auto track : tracks) { @@ -500,557 +469,290 @@ class ForwardTrackMaker { } // loop on track } // removeHits - - /** @brief merges the FST and FTT hitmaps into a single hitmap - * The FTT hits are shifted by the number of FST sectors - * @param hitmap1: FST hitmap - * @param hitmap2: FTT hitmap - * @return void - */ - void mergeHitmaps( FwdDataSource::HitMap_t &hitmap1, FwdDataSource::HitMap_t &hitmap2 ){ - static const int numFstSectors = 3; - for ( auto kv : hitmap2 ){ - for ( auto hit : kv.second ){ - dynamic_cast( hit )->setSector( hit->getSector() + numFstSectors ); - hitmap1[kv.first + numFstSectors].push_back( hit ); - } - } - } // mergeHitmaps - - /** @brief cleanup the event-wise data structures - * - */ - void cleanup() { + void doEvent(unsigned long long int iEvent = 0) { /************** Cleanup ****************************************/ // Moved cleanup to the start of doEvent, so that the fit results // persist after the call - mTrackSeeds.clear(); + mRecoTracks.clear(); + mRecoTrackQuality.clear(); + mRecoTrackIdTruth.clear(); + mFitMoms.clear(); + mNumFstHits.clear(); + mFitStatus.clear(); + + + // Clear pointers to the track reps from previous event + for (auto p : mGlobalTrackReps) + delete p; + + mGlobalTrackReps.clear(); + + // Clear pointers to global tracks + for (auto p : mGlobalTracks) + delete p; + + mGlobalTracks.clear(); + mTrackResults.clear(); - mEventStats.reset(); - mTotalHitsRemoved = 0; /************** Cleanup **************************/ - } - bool useMcTrackFinding(){ - /*************************************************************/ - // Determine if we should use MC seed finding - /*************************************************************/ - bool mcTrackFinding = true; - if (mConfig.exists("TrackFinder")){ - mcTrackFinding = false; - } - if (mConfig.exists("TrackFinder") && mConfig.get( "TrackFinder:mc", false ) == false ){ - mcTrackFinding = false; - } - if (mConfig.exists("TrackFinder") && mConfig.get( "TrackFinder:active", true ) == false){ - mcTrackFinding = true; + if (mGenHistograms ){ + mQualityPlotter->startEvent(); // starts the timer for this event } - return mcTrackFinding; - } - /** - * @brief Perform the track finding - * Creates a list of track seeds from the hitmaps - * Retrieve them using `getTrackSeeds()` - */ - void findTrackSeeds() { - cleanup(); - /*************************************************************/ - // Get the hitmaps - /*************************************************************/ - long long itStart = FwdTrackerUtils::nowNanoSecond(); - FwdDataSource::HitMap_t &fttHitmap = mDataSource->getFttHits(); - FwdDataSource::HitMap_t &fstHitmap = mDataSource->getFstHits(); + mTotalHitsRemoved = 0; /*************************************************************/ - // Determine seed finding mode + // Step 1 + // Load and sort the hits /*************************************************************/ - string hitmapSource = mConfig.get("TrackFinder:source", "ftt"); - LOG_INFO << "Hitmap Source: " << hitmapSource << endm; - mSeedSource = kSeqSeed; // default to FST - if (hitmapSource == "fst") - mSeedSource = kFstSeed; - else if (hitmapSource == "ftt") - mSeedSource = kFttSeed; - else if (hitmapSource == "seq") - mSeedSource = kSeqSeed; - else if (hitmapSource == "sim") - mSeedSource = kSimSeed; - LOG_INFO << "Performing Fwd Seed finding with mode: " << mConfig.get("TrackFinder:source", "ftt") << " = " << mSeedSource << endm; + long long itStart = FwdTrackerUtils::nowNanoSecond(); + FwdDataSource::HitMap_t &hitmap = mDataSource->getFttHits();; FwdDataSource::McTrackMap_t &mcTrackMap = mDataSource->getMcTracks(); + fillHistograms(); long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + if (mGenHistograms) + mHist["Step1Duration"]->Fill( duration ); - mEventStats.mStep1Duration.push_back( duration ); - /*************************************************************/ - // DO MC Track Finding (if set to do so) - if (useMcTrackFinding()) { - doMcTrackFinding(mcTrackMap, mSeedSource); - mEventStats.mNumSeeds = mTrackSeeds.size(); - long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - mEventStats.mSeedFindingDuration.push_back( duration2 ); - return; - } else { - LOG_DEBUG << "Performing Standard Track Finding" << endm; - } - /*************************************************************/ + bool mcTrackFinding = true; - /*************************************************************/ - // Standard Track Finding - size_t nIterations = mConfig.get("TrackFinder:nIterations", 0); - for (size_t iIteration = 0; iIteration < nIterations; iIteration++) { - if ( mSeedSource == kSimSeed){ - mergeHitmaps( fstHitmap, fttHitmap ); + if (mConfig.exists("TrackFinder")) + mcTrackFinding = false; + + /***********************************************/ + // MC Track Finding + if (mcTrackFinding) { + LOG_DEBUG << "MC TRACK FINDING " << endm; + doMcTrackFinding(mcTrackMap); + + /***********************************************/ + // REFIT with Silicon hits + if (mConfig.get("TrackFitter:refitSi", true)) { + addSiHitsMc(); } else { - if ( mSeedSource == kFstSeed || mSeedSource == kSeqSeed ){ - doSeedFindingIteration(iIteration, fstHitmap); - } - if ( mSeedSource == kFttSeed || mSeedSource == kSeqSeed){ - doSeedFindingIteration(iIteration, fttHitmap); - } + LOG_DEBUG << "Skipping FST Hits" << endm; + // skip Si refit } - } // iIteration - /*************************************************************/ - mEventStats.mNumSeeds = mTrackSeeds.size(); - long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - mEventStats.mSeedFindingDuration.push_back( duration2 ); - } // FindTrackSeeds + /***********************************************/ + if (mConfig.get("TrackFitter:refitGBL", true)) { + for (size_t i = 0; i < mGlobalTracks.size(); i++) { + mTrackFitter->refitTrackWithGBL(mGlobalTracks[i]); + } + } - std::vector< genfit::GFRaveVertex * > findFwdVertices( const vector &globalTracks ){ - // we will return a vector of vertices - std::vector< genfit::GFRaveVertex * > raveVertices; - - - // The RAVE factory needs the (bare) track pointers for vertex finding - vector tracks; - for ( auto gtr : globalTracks ){ - if ( gtr.mTrack ){ - tracks.push_back( gtr.mTrack.get() ); + if (mGenHistograms ){ + mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus); } + return; } + /***********************************************/ - bool useBeamConstraint = false; - if ( useBeamConstraint ){ - // TODO: load "official" beamline constraint parameters - TMatrixDSym bscm(3); - const double bssXY = 2.0; - bscm(0, 0) = bssXY*bssXY; - bscm(1, 1) = bssXY*bssXY; - bscm(2, 2) = 50.5 * 50.5; - mGFRVertices.setBeamspot( TVector3( 0, 0, 0 ), bscm ); + /***********************************************/ + // Standard Track Finding + // plus initial fit + size_t nIterations = mConfig.get("TrackFinder:nIterations", 0); + for (size_t iIteration = 0; iIteration < nIterations; iIteration++) { + doTrackIteration(iIteration, hitmap); + } + /***********************************************/ + + /***********************************************/ + // REFIT with Silicon hits + if (mConfig.get("TrackFitter:refitSi", true)) { + addSiHits(); + } else { + // Skipping Si Refit } + /***********************************************/ + if ( mGenHistograms ){ + mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus); + } + } // doEvent + void fitTrack(Seed_t &track) { - mGFRVertices.findVertices( &raveVertices, tracks, useBeamConstraint ); - LOG_DEBUG << "raveVertices.size() = " << raveVertices.size() << endm; - for ( auto vert : raveVertices ){ - LOG_DEBUG << TString::Format( "GFRaveVertex vertex @(%f, %f, %f)\n\n", vert->getPos().X(), vert->getPos().Y(), vert->getPos().Z() ) << endm; - LOG_DEBUG << "GFRaveVertex\n"; - // LOG_DEBUG << "Position: "; vert->getPos().Print(); - // LOG_DEBUG << "Covariance: "; vert->getCov().Print(); - LOG_DEBUG << "Ndf: " << vert->getNdf() << ", Chi2: " << vert->getChi2() << ", Id: " << vert->getId() << "\n"; - LOG_DEBUG << "Number of tracks: " << vert->getNTracks() << "\n"; + if ( mGenHistograms ){ + mHist["FitStatus"]->Fill("Seeds", 1); } - // if there is no Event Vertex, then we will use the first vertex found - // if ( raveVertices.size() > 0 ){ - // mEventVertex = raveVertices[0]->getPos(); - // // mEventVertexHit.setPos( mEventVertex ); - // } + // Calculate the MC info first and check filters + int idt = 0; + double qual = 0; + idt = MCTruthUtils::dominantContribution(track, qual); + + - return raveVertices; - } + TVector3 mcSeedMom; - /** - * @brief Perform a single fit from seed points - * - * @param seed : seed points from either FTT or FST - * @param includeVertex : include the primary vertex in the fit or not - * @return GenfitTrackResult : result of the fit - */ - GenfitTrackResult fitTrack(Seed_t &seed, TVector3 *momentumSeedState = nullptr) { - LOG_DEBUG << "FwdTracker::fitTrack->" << endm; - mEventStats.mAttemptedFits++; - // We will build this up as we go - GenfitTrackResult gtr; - - LOG_DEBUG << "--Setting seed on GenfitTrackResult, seed has " << seed.size() << " hits" << endm; - // First, set the seed information - gtr.setSeed( seed ); - - // If we are using a provided momentum state - if ( momentumSeedState ){ - LOG_DEBUG << "--FitTrack with provided momentum seed state" << endm; - mTrackFitter->fitTrack( seed, momentumSeedState ); - } else { - LOG_DEBUG << "--FitTrack without provided momentum seed state" << endm; - mTrackFitter->fitTrack( seed ); + auto mctm = mDataSource->getMcTracks(); + // get the MC track momentum if we can + if (mctm.count(idt)) { + auto mct = mctm[idt]; + mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); } - /*******************************************************/ - // Get the track from the fitter - // and set the track in the GenfitTrackResult - if (mTrackFitter->getTrack() != nullptr ){ - LOG_DEBUG << "--FitTrack found, setting seed and track only" << endm; - gtr.set( seed, mTrackFitter->getTrack() ); - if (gtr.mStatus && gtr.mStatus->isFitConvergedFully()) { - mEventStats.mGoodFits++; - } else { - mEventStats.mFailedFits++; + // Mc Filter + bool bailout = false; + if (qual < mConfig.get("TrackFitter.McFilter:quality-min", 0.0)) { + bailout = true; + // LOG_INFO << "BAIL OUT on Fit bc quality = " << qual << endm; + } + if (mctm.count(idt)) { + auto mct = mctm[idt]; + mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); + if (mct->mPt < mConfig.get("TrackFitter.McFilter:pt-min", 0.0) || + mct->mPt > mConfig.get("TrackFitter.McFilter:pt-max", 1e10)) { + bailout = true; + // LOG_INFO << "BAIL OUT on Fit bc Pt = " << mct->mPt << endm; + } + if (mct->mEta < mConfig.get("TrackFitter.McFilter:eta-min", 0) || + mct->mEta > mConfig.get("TrackFitter.McFilter:eta-max", 1e10)) { + bailout = true; + // LOG_INFO << "BAIL OUT on Fit bc eta = " << mct->mEta << endm; } - } else { // set the track as a failed fit, but keep the seed info - LOG_DEBUG << "--FitTrack failed, setting seed only" << endm; - mEventStats.mFailedFits++; + + } else { + // cannot find the track } - LOG_DEBUG << "<-FwdTracker::fitTrack complete" << endm; - return gtr; - } // fitTrack - + bailout = false; - /** - * @brief Loop on track seeds and fit each one - * - * Track fitting proceeds in 3 possible iterations - * 1. Fit seed points (without PV) - * 2. Look for additional hits in the other tracking detector - * 3. Refit the track with the additional hits - * 4. Refit the track with the primary vertex - * 5. look again and refit any additional hits - * - * @param trackSeeds : Track seeds - */ - void doTrackFitting( const std::vector &trackSeeds) { - LOG_DEBUG << ">>doTrackFitting" << endm; - if (!mDoTrackFitting) - return; - long long itStart = FwdTrackerUtils::nowNanoSecond(); + TVector3 p; + p.SetPtEtaPhi( 0, -999, 0 ); + genfit::FitStatus fitStatus; + + genfit::AbsTrackRep *trackRep = nullptr;//new genfit::RKTrackRep(211); // pdg for pi+ + genfit::Track *genTrack = nullptr;//new genfit::Track( trackRep, TVector3(0, 0, 0), TVector3(0, 0, 0) ); - std::vector globalTracks; - std::vector primaryTracks; - - // Should we try to refit the track with aadditional points from other detectors? - const bool doRefit = mConfig.get("TrackFitter:refit", false); - LOG_INFO << "TrackFitter:refit = " << doRefit << endm; - - // Should we use the MC momentum as a seed for the fit? - const bool useMcSeedMomentum = mConfig.get("TrackFitter:mcSeed", false); - LOG_INFO << "TrackFitter:mcSeed = " << useMcSeedMomentum << endm; - - LOG_DEBUG << "Starting track fitting loop, mTrackResults.size() = " << mTrackResults.size() << endm; - LOG_DEBUG << "Starting Track fitting loop on " << trackSeeds.size() << " track seeds" << endm; - size_t index = 0; - for (auto t : trackSeeds) { - - GenfitTrackResult gtrGlobalRefit; // will store refit if needed - LOG_DEBUG << "\tTrack seed initial global fit #" << index << endm; - /***********************************************************************************************************/ - // Tracking Step 1 - // Fit each accepted track seed - - // If we are using MC momentum get it from associated track - TVector3 momentumSeedStateMc; - TVector3 *pMomSeedState = nullptr; - int idt = 0; - double qual = 0; - // Get the quality and MC truth id - idt = MCTruthUtils::dominantContribution(t, qual); - LOG_INFO << "\t\tMc Match idTruth=" << idt << ", quality = " << qual << endm; - if (true == useMcSeedMomentum) { - /*******************************************************/ - // Only for Simulation - // Calculate the MC info first and check filters - - auto mctm = mDataSource->getMcTracks(); - // get the MC track momentum if we can (may be used for state seed) - if (mctm.count(idt)) { - auto mct = mctm[idt]; - momentumSeedStateMc.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); - // pMomSeedState = &momentumSeedStateMc; - } else { - LOG_WARN << "\tRequested MC momentum for fit seed, but couldnt find MC Track for id: " << idt << ", qual: " << qual << endm; - } - /*******************************************************/ - } // else if pMomSeedState = nullptr, a seed momentum will be computed from seed points by tracker - - // Fit the track seed and get the GenfitTrackResult - GenfitTrackResult gtrGlobal = fitTrack(t, pMomSeedState); - gtrGlobal.setDCA( mEventVertex ); - - LOG_DEBUG << "\tFit track seed with " << gtrGlobal.mSeed.size() << " hits" << endm; - LOG_DEBUG << "\t\t McTrack Id = " << gtrGlobal.mIdTruth << ", QA = " << gtrGlobal.mQaTruth << endm; - // End Step 1 - /*******************************************************/ - - - // if the first fit fails then we cannot proceed with the refit steps - if (gtrGlobal.mIsFitConvergedPartially == false) { - LOG_WARN << "\tInitial fitting failed for seed " << index << endm; - LOG_DEBUG << "\tFitting failed for seed " << index << endm; - LOG_DEBUG << "\tSkipping the refit steps but saving the seed and failed fit" << endm; - globalTracks.push_back( gtrGlobal ); - index++; - continue; - // BREAK OUT OF THE LOOP - } - if (doRefit == false) { - LOG_INFO << "\tRefit is disabled, saving the seed and initial fit" << endm; - gtrGlobal.isPrimary = false; - globalTracks.push_back( gtrGlobal ); - index++; - continue; - // BREAK OUT OF THE LOOP - } - /***********************************************************************************************************/ - // Tracking Step 2 - // Look for additional hits in the other tracking detector - // and add the new hits to the track - - // If requested, use the MC track finding to add hits to the track - if (useMcTrackFinding()) { - if (mSeedSource != kFttSeed) addFttHitsMc( gtrGlobal ); - if (mSeedSource != kFstSeed) addFstHitsMc( gtrGlobal ); - // globalTracks.push_back( gtrGlobalRefit ); - // index++; - // continue; // below is for "real" track finding only, for MC jump to next track - } else { - // If we are not using MC track finding, - // then we will look for additional hits via projections - if (mSeedSource != kFttSeed){ // Look for FTT hits if it was not the original seed source - for ( int i = 0; i < FwdSystem::sNFttLayers; i++ ){ - addFttHits( gtrGlobal, i ); - } - } - if (mSeedSource != kFstSeed ){ // Look for FST hits if it was not the original seed source - for ( int i = 0; i < FwdSystem::sNFstLayers; i++ ){ - addFstHits( gtrGlobal, i ); - } - } - // global refit + if (mDoTrackFitting && !bailout) { + if ( mGenHistograms ){ + mHist["FitStatus"]->Fill("AttemptFit", 1); } - // End Step 2 - /***********************************************************************************************************/ - - /***********************************************************************************************************/ - // Tracking Step 3: Fit the new global track with additional hits - gtrGlobalRefit = fitTrack( gtrGlobal.mSeed, >rGlobal.mMomentum ); - gtrGlobalRefit.setDCA( mEventVertex ); - // End Step 3 - /***********************************************************************************************************/ - - /***********************************************************************************************************/ - // Tracking Step 4: Save the best global track result - GenfitTrackResult *activeTrack = >rGlobal; - if ( gtrGlobalRefit.mIsFitConvergedPartially ){ - activeTrack = >rGlobalRefit; + + double vertex[3] = { mEventVertex.X(), mEventVertex.Y(), mEventVertex.Z() }; + + double * pVertex = 0; + if ( fabs(mEventVertex.X()) < 100 ){ + pVertex = vertex; // only use it if it has been set from default } - if ( !activeTrack->mIsFitConvergedPartially ){ - // should not be possible according to above logic... - LOG_WARN << "\tFWD global track fit failed (both initial + refit)" << endm; - continue; + + if (true == mConfig.get("TrackFitter:mcSeed", false)) { + // use the MC pt, eta, phi as the seed for fitting + p = mTrackFitter->fitTrack(track, pVertex, &mcSeedMom); + } else { + // Normal case, real data + p = mTrackFitter->fitTrack(track, pVertex); } - // if the refit is successful, - // then we will add the track to the globalTracks - // if not keep the original global track - activeTrack->isPrimary = false; // should be default but just make sure - globalTracks.push_back( *activeTrack ); // save this global track result - // End Step 4 - /***********************************************************************************************************/ - } // loop on track seeds - - long long duration1 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - mEventStats.mFitDuration.push_back( duration1 ); - float perGood = (float) mEventStats.mGoodFits / (float) mEventStats.mAttemptedFits; - float perFailed = (float) mEventStats.mFailedFits / (float) mEventStats.mAttemptedFits; - float perCardinals = (float) mEventStats.mGoodCardinals / (float) mEventStats.mGoodFits; - LOG_DEBUG << "\tGlobal Track Fitting Results:" << - TString::Format( - "Attempts = %d, Good = %d (%f%%), Failed = %d (%f%%), GoodCardinals = %d (%f%%)", - mEventStats.mAttemptedFits, - mEventStats.mGoodFits, - perGood, - mEventStats.mFailedFits, - perFailed, - mEventStats.mGoodCardinals, - perCardinals ) << endm; - - const bool do_fwd_vertex_finding = true; - if (do_fwd_vertex_finding){ - /***********************************************************************************************************/ - // Step 5: Find the FWD Vertices - LOG_DEBUG << "\tStarting Track Fitting Step 3 (FWD Vertex Finding)" << endm; - auto fwdVertices = findFwdVertices( globalTracks ); - mEventStats.mNumFwdVertices = fwdVertices.size(); - - for ( auto vert : fwdVertices ){ - LOG_DEBUG << "\tFound FWD Vertex @(" << vert->getPos().X() << ", " << vert->getPos().Y() << ", " << vert->getPos().Z() << ")" << endm; - LOG_DEBUG << "\t\tvs mEventVertexHit: " << mEventVertexHit.getX() << ", " << mEventVertexHit.getY() << ", " << mEventVertexHit.getZ() << endm; + if ( mGenHistograms ){ + if (p.Perp() > 1e-3) { + mHist["FitStatus"]->Fill("GoodFit", 1); + } else { + mHist["FitStatus"]->Fill("BadFit", 1); + } } - // End Step 5 - /***********************************************************************************************************/ - } else { - LOG_INFO << "Event configuration is skipping FWD vertex finding" << endm; - } + genTrack = new genfit::Track(*mTrackFitter->getTrack()); + genTrack->setMcTrackId(idt); + GenfitTrackResult gtr( track.size(), 0, track, genTrack ); - const bool do_fwd_primary_fitting = true; - /***********************************************************************************************************/ - // Step 6: Refit the track with the primary vertex - index = 0; - if (do_fwd_primary_fitting){ - // Now try refitting every track with the primary vertex - for (auto >r : globalTracks) { - LOG_INFO << "Refitting Track " << index << ", McId=" << gtr.mIdTruth << " with Primary Vertex, seed already has: " << gtr.mSeed.size() << " hits" << endm; - LOG_INFO << "mEventVertexHit: " << mEventVertexHit.getX() << ", " << mEventVertexHit.getY() << ", " << mEventVertexHit.getZ() << endm; - // just use the global track to build the track that will use the PV also - Seed_t seedWithPV = gtr.mSeed; - seedWithPV.push_back( &mEventVertexHit ); - - // If we are using MC momentum get it from associated track - TVector3 momentumSeedStateMc; - TVector3 *pMomSeedState = >r.mMomentum; - // if (true == useMcSeedMomentum) { - // /*******************************************************/ - // // Only for Simulation - // // get the MC track momentum if we can (may be used for state seed) - // auto mctm = mDataSource->getMcTracks(); - // if (mctm.count(gtr.mIdTruth)) { - // auto mct = mctm[gtr.mIdTruth]; - // momentumSeedStateMc.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); - // pMomSeedState = &momentumSeedStateMc; - // LOG_INFO << "Setting momentum to MC Seed state value for primary refit" << endm; - // } else {} - // /*******************************************************/ - // } // else if pMomSeedState = nullptr, a seed momentum will be computed from seed points by tracker - - GenfitTrackResult gtrPV = fitTrack(seedWithPV, pMomSeedState); - if ( gtrPV.mIsFitConvergedFully ){ - mEventStats.mGoodPrimaryFits++; - } else { - mEventStats.mFailedPrimaryFits++; - continue; - } - gtrPV.setDCA( mEventVertex ); - gtrPV.isPrimary = true; - mEventStats.mAttemptedPrimaryFits ++; - primaryTracks.push_back( gtrPV ); - index++; + // assign the fit results to be saved + fitStatus = mTrackFitter->getStatus(); + trackRep = mTrackFitter->getTrackRep()->clone(); // Clone the track rep + + if ( mGenHistograms && genTrack->getFitStatus(genTrack->getCardinalRep())->isFitConverged() && p.Perp() > 1e-3) { + mHist["FitStatus"]->Fill("GoodCardinal", 1); } - // End Step 6 - /***********************************************************************************************************/ - } else { - LOG_INFO << "Event configuration is skipping primary track fitting" << endm; - } - float perGoodPrim = (float) mEventStats.mGoodPrimaryFits / (float) mEventStats.mAttemptedPrimaryFits; - float perFailedPrim = (float) mEventStats.mFailedPrimaryFits / (float) mEventStats.mAttemptedPrimaryFits; - LOG_DEBUG << "\tPrimary Track Fitting Results:" << - TString::Format( - "Attempts = %d, Good = %d (%f%%), Failed = %d (%f%%)", - mEventStats.mAttemptedPrimaryFits, - mEventStats.mGoodPrimaryFits, - perGoodPrim, - mEventStats.mFailedPrimaryFits, - perFailedPrim - ) << endm; - - // Add the global and primary tracks to the results - LOG_DEBUG << "Ending track fitting loop, mTrackResults.size() = " << mTrackResults.size() << endm; - mTrackResults.insert( mTrackResults.end(), globalTracks.begin(), globalTracks.end() ); - LOG_DEBUG << "Copied globals, now mTrackResults.size() = " << mTrackResults.size() << endm; - mTrackResults.insert( mTrackResults.end(), primaryTracks.begin(), primaryTracks.end() ); - - long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - LOG_DEBUG << "Track fitting took " << duration2 << "ms" << endm; - LOG_DEBUG << "We fit " << globalTracks.size() << " global tracks and " << primaryTracks.size() << " primary tracks, total = " << mTrackResults.size() << endm; - } // doTrackFitting - - /** - * @brief MC track finding builds track seeds from available hits using MC association - * - * @param mcTrackMap : Mc tracks - * @param useFttAsSource : Use FTT for seeds or (false) use Fst - */ - void doMcTrackFinding(FwdDataSource::McTrackMap_t &mcTrackMap, int seedSource) { - LOG_INFO << "Running MC Seed Finding, mode: " << seedSource << endm; + // Save everything (now use GenfitTrackResult) + mFitMoms.push_back(p); + mGlobalTracks.push_back(genTrack); + mGlobalTrackReps.push_back(trackRep); + mFitStatus.push_back(fitStatus); + mRecoTrackQuality.push_back(qual); + mRecoTrackIdTruth.push_back(idt); + mNumFstHits.push_back(0); + + mTrackResults.push_back( gtr ); + + LOG_DEBUG << "FwdTracker::fitTrack complete" << endm; + } // if (mDoTrackFitting && !bailout) + } - // If we want sequential MC track finding then do them each individually - if ( seedSource == kSeqSeed ){ - doMcTrackFinding( mcTrackMap, kFstSeed ); - doMcTrackFinding( mcTrackMap, kFttSeed ); - return; + void doTrackFitting( std::vector &tracks) { + long long itStart = FwdTrackerUtils::nowNanoSecond(); + // Fit each accepted track seed + for (auto t : tracks) { + fitTrack(t); } + long long itEnd = FwdTrackerUtils::nowNanoSecond(); + long long duration = (itEnd - itStart) * 1e-6; // milliseconds + if ( mGenHistograms ){ + this->mHist["FitDuration"]->Fill(duration); + } + // TODO: After tracking vertex finding... - mTrackSeedsThisIteration.clear(); - // we will build reco tracks from each McTrack - for (auto kv : mcTrackMap) { - - auto mc_track = kv.second; - LOG_DEBUG << "McTrack[ " << kv.first << " ]: nFtt=" << mc_track->mFttHits.size() << ", nFst=" << mc_track->mFstHits.size() << endm; + } - if (seedSource == kFttSeed && mc_track->mFttHits.size() < 2){ // require min 4 FTT hits on track - continue; - } + void doMcTrackFinding(FwdDataSource::McTrackMap_t &mcTrackMap) { - if (seedSource == kFstSeed && mc_track->mFstHits.size() < 2 ) { // require min 3 FST hits on track - LOG_DEBUG << "Skipping McSeedFinding bc FST hits < 2" << endm; - continue; - } + mQualityPlotter->startIteration(); - if ( seedSource == kSimSeed && mc_track->mFstHits.size() < 2 && mc_track->mFttHits.size() < 2 ){ + // we will build reco tracks from each McTrack + for (auto kv : mcTrackMap) { + + auto mc_track = kv.second; + if (mc_track->mHits.size() < 4){ // require min 4 hits on track continue; } std::set uvid; Seed_t track; - if ( seedSource != kFstSeed ){ // FTT is used unless we are ONLY considering FST - for (auto h : mc_track->mFttHits) { - track.push_back(h); - uvid.insert(static_cast(h)->_vid); - } - } - if (seedSource != kFttSeed ) { // FST - for (auto h : mc_track->mFstHits) { - track.push_back(h); - uvid.insert(static_cast(h)->_vid); - } + for (auto h : mc_track->mHits) { + track.push_back(h); + uvid.insert(static_cast(h)->_vid); } if (uvid.size() == track.size()) { // only add tracks that have one hit per volume - mTrackSeedsThisIteration.push_back(track); + mRecoTracks.push_back(track); int idt = 0; double qual = 0; idt = MCTruthUtils::dominantContribution(track, qual); + mRecoTrackQuality.push_back(qual); + mRecoTrackIdTruth.push_back(idt); } else { - //Skipping track that doesnt have hits on all layers + //Skipping track that doesnt have hits on all layers } } - LOG_DEBUG << "McTrackFinding Found: " << mTrackSeedsThisIteration.size() << " tracks" << endm; - // doTrackFitting(mTrackSeedsThisIteration); + LOG_DEBUG << "McTrackFinding Found: " << mRecoTracks.size() << " tracks" << endm; + + doTrackFitting(mRecoTracks); + + if ( mGenHistograms ){ + mQualityPlotter->afterIteration(0, mRecoTracks); + } + } - // Now save to the main reco track list - mTrackSeeds.insert( mTrackSeeds.end(), mTrackSeedsThisIteration.begin(), mTrackSeedsThisIteration.end() ); - } //doMcTrackFinding /** sliceHitMapInPhi * @brief Slices a hitmap into a phi section - * + * * @param inputMap INPUT hitmap to process * @param outputMap OUTPUT hitmap, will be cleared and filled with only the hits from inputMap that are within phi region * @param phi_min The minimum phi to accept * @param phi_max The maximum Phi to accept - * + * * @returns The number of hits in the outputMap */ size_t sliceHitMapInPhi( FwdDataSource::HitMap_t &inputMap, FwdDataSource::HitMap_t &outputMap, float phi_min, float phi_max ){ @@ -1068,18 +770,19 @@ class ForwardTrackMaker { } // loop on hits } // loop on map return n_hits_kept; - } // sliceHitMapInPhi + } - /** doSeedFindingOnHitmapSubset + /** doTrackingOnHitmapSubset * @brief Does track finding steps on a subset of hits (phi slice) * @param iIteration: tracking iteration (for determining params) * @param hitmap: the hitmap to use, should already be subset of original * @returns a list of track seeds */ - vector doSeedFindingOnHitmapSubset( size_t iIteration, FwdDataSource::HitMap_t &hitmap ) { + vector doTrackingOnHitmapSubset( size_t iIteration, FwdDataSource::HitMap_t &hitmap ) { long long itStart = FwdTrackerUtils::nowNanoSecond(); - std::vector acceptedTrackSeeds; + std::vector acceptedTracks; + std::vector rejectedTracks; /*************************************************************/ // Step 2 // build 2-hit segments (setup parent child relationships) @@ -1097,7 +800,7 @@ class ForwardTrackMaker { criteriaPath = "TrackFinder.SegmentBuilder"; } - clearCriteria( mTwoHitCrit ); + mTwoHitCrit.clear(); mTwoHitCrit = loadCriteria(criteriaPath); builder.addCriteria(mTwoHitCrit); @@ -1108,22 +811,19 @@ class ForwardTrackMaker { connPath = "TrackFinder.Connector"; unsigned int distance = mConfig.get(connPath + ":distance", 1); - if (mSeedSource == kFttSeed){ - distance = 2; // set distance to 2 for FTT - } - + FwdConnector connector(distance); builder.addSectorConnector(&connector); - LOG_DEBUG << "Connector added: " << endm; - // Get the segments and return an automaton object for further work + // Get the segments and return an automaton object for further work + KiTrack::Automaton automaton = builder.get1SegAutomaton(); LOG_DEBUG << TString::Format( "nSegments=%lu", automaton.getSegments().size() ).Data() << endm; LOG_DEBUG << TString::Format( "nConnections=%u", automaton.getNumberOfConnections() ).Data() << endm; - if (automaton.getNumberOfConnections() > 9000 ){ + if (automaton.getNumberOfConnections() > 900 ){ LOG_ERROR << "Got too many connections, bailing out of tracking" << endm; - return acceptedTrackSeeds; + return acceptedTracks; } // at any point we can get a list of tracks out like this: @@ -1131,7 +831,8 @@ class ForwardTrackMaker { // we can apply an optional parameter to only get tracks with >=nHits in them long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - mEventStats.mStep2Duration.push_back(duration); + if (mGenHistograms) + mHist["Step2Duration"]->Fill( duration ); itStart = FwdTrackerUtils::nowNanoSecond(); /*************************************************************/ @@ -1145,20 +846,35 @@ class ForwardTrackMaker { if (false == mConfig.exists(criteriaPath)) criteriaPath = "TrackFinder.ThreeHitSegments"; - clearCriteria( mThreeHitCrit ); + mThreeHitCrit.clear(); mThreeHitCrit = loadCriteria(criteriaPath); automaton.addCriteria(mThreeHitCrit); + automaton.lengthenSegments(); + + bool doAutomation = mConfig.get(criteriaPath + ":doAutomation", true); + bool doCleanBadStates = mConfig.get(criteriaPath + ":cleanBadStates", true); + + if (doAutomation) { + automaton.doAutomaton(); + } else { + //Not running Automation Step + } + + if (doAutomation && doCleanBadStates) { + automaton.cleanBadStates(); + } duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - mEventStats.mStep3Duration.push_back( duration ); - if (duration > 2000 || automaton.getNumberOfConnections() > 9000){ + if (mGenHistograms) + mHist["Step3Duration"]->Fill( duration ); + if (duration > 200 || automaton.getNumberOfConnections() > 900){ LOG_WARN << "The Three Hit Criteria took more than 200ms to process, duration: " << duration << " ms" << endm; LOG_WARN << "bailing out (skipping subset HNN)" << endm; - + std::vector acceptedTracks; std::string subsetPath = "TrackFinder.Iteration[" + std::to_string(iIteration) + "].SubsetNN"; size_t minHitsOnTrack = mConfig.get(subsetPath + ":min-hits-on-track", FwdSystem::sNFttLayers); - acceptedTrackSeeds = automaton.getTracks(minHitsOnTrack); - return acceptedTrackSeeds; + acceptedTracks = automaton.getTracks(minHitsOnTrack); + return acceptedTracks; } itStart = FwdTrackerUtils::nowNanoSecond(); @@ -1199,48 +915,46 @@ class ForwardTrackMaker { subset.calculateBestSet(comparer, quality); - acceptedTrackSeeds = subset.getAccepted(); + acceptedTracks = subset.getAccepted(); // this call takes a long time due to possible huge combinatorics. // rejectedTracks = subset.getRejected(); - // LOG_DEBUG << "We had " << tracks.size() << " tracks. Accepted = " << acceptedTrackSeeds.size() << ", Rejected = " << rejectedTracks.size() << endm; + // LOG_DEBUG << "We had " << tracks.size() << " tracks. Accepted = " << acceptedTracks.size() << ", Rejected = " << rejectedTracks.size() << endm; } else { // the subset and hit removal size_t minHitsOnTrack = mConfig.get(subsetPath + ":min-hits-on-track", FwdSystem::sNFttLayers); - acceptedTrackSeeds = automaton.getTracks(minHitsOnTrack); + acceptedTracks = automaton.getTracks(minHitsOnTrack); }// subset off duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - mEventStats.mStep4Duration.push_back( duration ); + if (mGenHistograms) + mHist["Step4Duration"]->Fill( duration ); if (duration > 500){ LOG_WARN << "The took more than 500ms to process, duration: " << duration << " ms" << endm; - LOG_WARN << "We got " << acceptedTrackSeeds.size() << " tracks this round" << endm; + LOG_WARN << "We got " << acceptedTracks.size() << " tracks this round" << endm; } - LOG_DEBUG << "We got " << acceptedTrackSeeds.size() << " tracks this round" << endm; - return acceptedTrackSeeds; - } // doSeedFindingOnHitmapSubset - - /** - * @brief Main tracking procedure - * - * @param iIteration : The track iteration - * @param hitmap : the hitmap of available hits per plane - */ - void doSeedFindingIteration(size_t iIteration, FwdDataSource::HitMap_t &hitmap) { + LOG_DEBUG << "We got " << acceptedTracks.size() << " tracks this round" << endm; + return acceptedTracks; + } // doTrackingOnHitmapSubset + + void doTrackIteration(size_t iIteration, FwdDataSource::HitMap_t &hitmap) { // empty the list of reco tracks for the iteration - mTrackSeedsThisIteration.clear(); + mRecoTracksThisItertion.clear(); // check to see if we have hits! size_t nHitsThisIteration = nHitsInHitMap(hitmap); - const int minHitsToConsider = 3; - if (nHitsThisIteration < minHitsToConsider) { + if (nHitsThisIteration < 4) { // No hits left in the hitmap! Skipping this iteration - LOG_INFO << "No hits to consider in this iteration, skipping" << endm; return; } + // this starts the timer for the iteration + if ( mGenHistograms ){ + mQualityPlotter->startIteration(); + } + std::string pslPath = "TrackFinder.Iteration["+ std::to_string(iIteration) + "]:nPhiSlices"; if ( false == mConfig.exists( pslPath ) ) pslPath = "TrackFinder:nPhiSlices"; size_t phi_slice_count = mConfig.get( pslPath, 1 ); @@ -1250,12 +964,12 @@ class ForwardTrackMaker { /*************************************************************/ // Steps 2 - 4 here /*************************************************************/ - auto acceptedTracks = doSeedFindingOnHitmapSubset( iIteration, hitmap ); - mTrackSeedsThisIteration.insert( mTrackSeedsThisIteration.end(), acceptedTracks.begin(), acceptedTracks.end() ); + auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, hitmap ); + mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() ); } else { FwdDataSource::HitMap_t slicedHitMap; - + if ( phi_slice_count == 0 || phi_slice_count > 100 ){ LOG_WARN << "Invalid phi_slice_count = " << phi_slice_count << ", resetting to 1" << endm; phi_slice_count= 1; @@ -1265,32 +979,31 @@ class ForwardTrackMaker { float phi_min = phi_slice_index * phi_slice - TMath::Pi(); float phi_max = (phi_slice_index + 1) * phi_slice - TMath::Pi(); - LOG_INFO << TString::Format( "phi slice = (%f, %f)", phi_min, phi_max ) << endm; /*************************************************************/ - // Step 1 + // Step 1A // Slice the hitmap into a phi section if needed // If we do that, check again that we arent wasting time on empty sections /*************************************************************/ size_t nHitsThisSlice = 0; if ( phi_slice_count > 1 ){ nHitsThisSlice = sliceHitMapInPhi( hitmap, slicedHitMap, phi_min, phi_max ); - if ( nHitsThisSlice < minHitsToConsider ) { + if ( nHitsThisSlice < 4 ) { continue; } } else { // no need to slice // I think this incurs a copy, maybe we can find a way to avoid. slicedHitMap = hitmap; } - + /*************************************************************/ // Steps 2 - 4 here /*************************************************************/ - auto acceptedTracks = doSeedFindingOnHitmapSubset( iIteration, slicedHitMap ); - mTrackSeedsThisIteration.insert( mTrackSeedsThisIteration.end(), acceptedTracks.begin(), acceptedTracks.end() ); + auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, slicedHitMap ); + mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() ); } //loop on phi slices }// if loop on phi slices - + LOG_INFO << "."; /*************************************************************/ // Step 5 // Remove the hits from any track that was found @@ -1299,164 +1012,188 @@ class ForwardTrackMaker { if ( false == mConfig.exists( hrmPath ) ) hrmPath = "TrackFinder.HitRemover"; if ( true == mConfig.get( hrmPath + ":active", true ) ){ - removeHits( hitmap, mTrackSeedsThisIteration ); + removeHits( hitmap, mRecoTracksThisItertion ); } + + LOG_DEBUG << " FITTING " << mRecoTracksThisItertion.size() << " now" << endm; - LOG_DEBUG << " Found " << mTrackSeedsThisIteration.size() << " seed tracks this iteration" << endm; + if ( mRecoTracksThisItertion.size() < 201 ){ + doTrackFitting( mRecoTracksThisItertion ); + } else { + LOG_ERROR << "BAILING OUT of fit, too many track candidates" << endm; + } + + if ( mGenHistograms ){ + mQualityPlotter->afterIteration( iIteration, mRecoTracksThisItertion ); + } + // Add the set of all accepted tracks (this iteration) to our collection of found tracks from all iterations - mTrackSeeds.insert( mTrackSeeds.end(), mTrackSeedsThisIteration.begin(), mTrackSeedsThisIteration.end() ); - } // doSeedFindingIteration + mRecoTracks.insert( mRecoTracks.end(), mRecoTracksThisItertion.begin(), mRecoTracksThisItertion.end() ); - /** - * @brief Adds compatible FST hits to tracks seeded with FTT - * - */ - void addFstHitsMc( GenfitTrackResult >r ) { + } // doTrackIteration + + void addSiHitsMc() { FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); - if ( gtr.mStatus->isFitConverged() == false || gtr.mMomentum.Perp() < 1e-3) { - LOG_DEBUG << "Skipping addFstHitsMc, fit failed" << endm; - return; - } - mEventStats.mPossibleReFit++; - Seed_t fstHitsThisTrack; - - for (size_t j = 0; j < 3; j++) { - for (auto h0 : hitmap[j]) { - if (dynamic_cast(h0)->_tid == gtr.mIdTruth) { - fstHitsThisTrack.push_back(h0); - break; + + for (size_t i = 0; i < mTrackResults.size(); i++) { + GenfitTrackResult >r = mTrackResults[i]; + + if ( gtr.status.isFitConverged() == false || gtr.momentum.Perp() < 1e-3) { + LOG_DEBUG << "Skipping addSiHitsMc, fit failed" << endm; + return; + } + + if ( mGenHistograms){ + mHist["FitStatus"]->Fill("PossibleReFit", 1); + } + + Seed_t si_hits_for_this_track(3, nullptr); + + for (size_t j = 0; j < 3; j++) { + for (auto h0 : hitmap[j]) { + if (dynamic_cast(h0)->_tid == gtr.track->getMcTrackId()) { + si_hits_for_this_track[j] = h0; + break; + } + } // loop on hits in this layer of hitmap + } // loop on hitmap layers + + size_t nSiHitsFound = 0; + if ( si_hits_for_this_track[0] != nullptr ) nSiHitsFound++; + if ( si_hits_for_this_track[1] != nullptr ) nSiHitsFound++; + if ( si_hits_for_this_track[2] != nullptr ) nSiHitsFound++; + LOG_DEBUG << "Found " << nSiHitsFound << " FST Hits on this track (MC lookup)" << endm; + + if ( mGenHistograms ){ + this->mHist[ "nSiHitsFound" ]->Fill( 1, ( si_hits_for_this_track[0] != nullptr ? 1 : 0 ) ); + this->mHist[ "nSiHitsFound" ]->Fill( 2, ( si_hits_for_this_track[1] != nullptr ? 1 : 0 ) ); + this->mHist[ "nSiHitsFound" ]->Fill( 3, ( si_hits_for_this_track[2] != nullptr ? 1 : 0 ) ); + } + + if (nSiHitsFound >= 1) { + if ( mGenHistograms ){ + mHist["FitStatus"]->Fill("AttemptReFit", 1); + } + TVector3 p = mTrackFitter->refitTrackWithSiHits(gtr.track, si_hits_for_this_track); + + if ( mGenHistograms ){ + if (p.Perp() == mFitMoms[i].Perp()) { + mHist["FitStatus"]->Fill("BadReFit", 1); + LOG_DEBUG << "refitTrackWithSiHits failed refit" << endm; + } else { + mHist["FitStatus"]->Fill("GoodReFit", 1); + gtr.setFst( si_hits_for_this_track, mTrackFitter->getTrack() ); + } } - } // loop on hits in this layer of hitmap - } // loop on hitmap layers - - LOG_DEBUG << "Found " << gtr.mSeed.size() << " existing seed points" << endm; - LOG_DEBUG << "Adding " << fstHitsThisTrack.size() << " new FST seed points" << endm; - - if (fstHitsThisTrack.size() >= 1) { - mEventStats.mAttemptedReFits++; - gtr.mSeed.insert( gtr.mSeed.end(), fstHitsThisTrack.begin(), fstHitsThisTrack.end() ); - } // we have 3 Si hits to refit with - } // addFstHitsMc - - /** - * @brief Adds compatible FTT hits to tracks seeded with FST - * - * @param gtr : The GenfitTrackResult to add FTT hits to - * @param disk : The FTT disk number - * @return Seed_t : The combined seed points - */ - void addFttHits( GenfitTrackResult >r, size_t disk ) { - FwdDataSource::HitMap_t hitmap = mDataSource->getFttHits(); - if ( disk > 3 ) { - LOG_WARN << "Invalid FTT disk number: " << disk << ", cannot add Ftt points to track" << endm; - return; - } - if (gtr.mIsFitConverged != true) - return; - mEventStats.mPossibleReFit++; - Seed_t hits_near_plane; - try { - auto msp = mTrackFitter->projectToFtt(disk, gtr.mTrack); - - // now look for Ftt hits near the specified state - hits_near_plane = findFttHitsNearProjectedState(hitmap[disk], msp); - LOG_DEBUG << " Found #FTT hits on plane #" << disk << TString::Format( " = [%ld]", hits_near_plane.size() ) << endm; - } catch (genfit::Exception &e) { - // Failed to project - LOG_WARN << "Unable to get Ftt projections: " << e.what() << endm; - } + mNumFstHits[i] = nSiHitsFound; + mFitMoms[i] = p; + } // we have 3 Si hits to refit with - LOG_DEBUG << "Found " << gtr.mSeed.size() << " existing seed points" << endm; + if ( mGenHistograms ){ + mHist["FitStatus"]->Fill( TString::Format( "w%luSi", nSiHitsFound ).Data(), 1 ); + } - if ( hits_near_plane.size() > 0 ){ - mEventStats.mAttemptedReFits++; - LOG_DEBUG << "Adding " << hits_near_plane.size() << " new FTT seed points" << endm; - gtr.mSeed.insert( gtr.mSeed.end(), hits_near_plane.begin(), hits_near_plane.end() ); - } - return; - } // addFttHits + } // loop on the global tracks + } // ad Si hits via MC associations - /** - * @brief Adds compatible FTT hits using MC info - * - */ - void addFttHitsMc( GenfitTrackResult >r ) { - LOG_DEBUG << "Looking for FTT hits on this track (MC lookup)" << endm; - LOG_DEBUG << "Track TruthId = " << gtr.mIdTruth << " vs. " << gtr.mTrack->getMcTrackId() << endm; - FwdDataSource::HitMap_t hitmap = mDataSource->getFttHits(); - if ( gtr.mStatus->isFitConverged() == false || gtr.mMomentum.Perp() < 1e-6) { - LOG_DEBUG << "Skipping addFttHitsMc on this track, fit failed" << endm; - return; - } + void addSiHits() { + FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); + + // loop on global tracks + for (size_t i = 0; i < mGlobalTracks.size(); i++) { + if (mGlobalTracks[i]->getFitStatus(mGlobalTracks[i]->getCardinalRep())->isFitConverged() == false) { + // Original Track fit did not converge, skipping + return; + } + + if ( mGenHistograms ){ + mHist["FitStatus"]->Fill("PossibleReFit", 1); + } + + Seed_t hits_near_disk0; + Seed_t hits_near_disk1; + Seed_t hits_near_disk2; + try { + auto msp2 = mTrackFitter->projectToFst(2, mGlobalTracks[i]); + auto msp1 = mTrackFitter->projectToFst(1, mGlobalTracks[i]); + auto msp0 = mTrackFitter->projectToFst(0, mGlobalTracks[i]); + + // now look for Si hits near these + hits_near_disk2 = findSiHitsNearMe(hitmap[2], msp2); + hits_near_disk1 = findSiHitsNearMe(hitmap[1], msp1); + hits_near_disk0 = findSiHitsNearMe(hitmap[0], msp0); + } catch (genfit::Exception &e) { + // Failed to project to Si disk: ", e.what() + } + + vector hits_to_add; - mEventStats.mPossibleReFit++; - Seed_t fttHitsForThisTrack; + size_t nSiHitsFound = 0; // this is really # of disks on which a hit is found - for (size_t j = 0; j < 4; j++) { - for (auto h0 : hitmap[j]) { - if (dynamic_cast(h0)->_tid == gtr.mIdTruth) { - fttHitsForThisTrack.push_back( h0 ); - break; + if ( mGenHistograms ){ + this->mHist[ "nSiHitsFound" ]->Fill( 1, hits_near_disk0.size() ); + this->mHist[ "nSiHitsFound" ]->Fill( 2, hits_near_disk1.size() ); + this->mHist[ "nSiHitsFound" ]->Fill( 3, hits_near_disk2.size() ); + } + + // TODO: HANDLE multiple points found? + if ( hits_near_disk0.size() == 1 ) { + hits_to_add.push_back( hits_near_disk0[0] ); + nSiHitsFound++; + } else { + hits_to_add.push_back( nullptr ); + } + if ( hits_near_disk1.size() == 1 ) { + hits_to_add.push_back( hits_near_disk1[0] ); + nSiHitsFound++; + } else { + hits_to_add.push_back( nullptr ); + } + if ( hits_near_disk2.size() == 1 ) { + hits_to_add.push_back( hits_near_disk2[0] ); + nSiHitsFound++; + } else { + hits_to_add.push_back( nullptr ); + } + + if (nSiHitsFound >= 1) { + if ( mGenHistograms ){ + mHist["FitStatus"]->Fill("AttemptReFit", 1); + } + // LOG_INFO << "Fitting on GlobalTrack : " << mGlobalTracks[i] << " with " << nSiHitsFound << " si hits" << endm; + TVector3 p = mTrackFitter->refitTrackWithSiHits(mGlobalTracks[i], hits_to_add); + size_t lengthGTR = mTrackResults.size(); + if ( lengthGTR >= 1 ){ + mTrackResults[ lengthGTR - 1 ].setFst( hits_to_add, mTrackFitter->getTrack() ); + } else { + LOG_ERROR << "Fit Results not found" << endm; } - } // loop on hits in this layer of hitmap - } // loop on hitmap layers - - LOG_DEBUG << "Found " << fttHitsForThisTrack.size() << " FTT Hits on this track (MC lookup)" << endm; - - if (fttHitsForThisTrack.size() >= 1) { - mEventStats.mAttemptedReFits++; - gtr.mSeed.insert( gtr.mSeed.end(), fttHitsForThisTrack.begin(), fttHitsForThisTrack.end() ); - } // we have at least one Fst hit to refit with - } // add Ftt hits via MC associations - - /** - * @brief Adds compatible FST hits to a track - * - * @param gtr : The GenfitTrackResult to add FST hits to - * @param disk : The FST disk number - */ - void addFstHits( GenfitTrackResult >r, size_t disk ) { - FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); - if (gtr.mIsFitConverged == false) { - // Original Track fit did not converge, skipping - return; - } - if ( disk > 2 ){ - LOG_ERROR << "Invalid FST disk number: " << disk << endm; - return; - } - mEventStats.mPossibleReFit++; - Seed_t nearby_hits; - try { - // get measured state on plane at specified disk - auto msp = mTrackFitter->projectToFst(disk, gtr.mTrack); - // now look for Si hits near this state - nearby_hits = findFstHitsNearProjectedState(hitmap[disk], msp); - } catch (genfit::Exception &e) { - LOG_WARN << "Unable to get projections: " << e.what() << endm; - } - LOG_DEBUG << "Track already has " << gtr.mSeed.size() << " existing seed points" << endm; + if ( mGenHistograms ){ + if (p.Perp() == mFitMoms[i].Perp()) { + mHist["FitStatus"]->Fill("BadReFit", 1); + } else { + mHist["FitStatus"]->Fill("GoodReFit", 1); + } + } - if ( nearby_hits.size() > 0 ){ - mEventStats.mAttemptedReFits++; - LOG_DEBUG << "Adding " << nearby_hits.size() << " new FST seed points from disk " << disk << endm; - gtr.mSeed.insert( gtr.mSeed.end(), nearby_hits.begin(), nearby_hits.end() ); - } - return; - } // addFstHits - - /** - * @brief Finds FST hits near projected state - * - * @param available_hits : FST hits to consider - * @param msp : measured state on plabe from existing track projection - * @param dphi : search distance in phi - * @param dr : search distance in r - * @return Seed_t : compatible FST hits - */ - Seed_t findFstHitsNearProjectedState(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dphi = 0.004 * 20.5, double dr = 2.75 * 2) { + // mGlobalTracks[i] = mTrackFitter->getTrack(); + mNumFstHits[i] = nSiHitsFound; + mFitMoms[i] = p; + + } else { + // unable to refit + } + + if ( mGenHistograms ){ + mHist["FitStatus"]->Fill( TString::Format( "w%luSi", nSiHitsFound ).Data(), 1 ); + } + + } // loop on globals + } // addSiHits + + Seed_t findSiHitsNearMe(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dphi = 0.004 * 9.5, double dr = 2.75) { double probe_phi = TMath::ATan2(msp.getPos().Y(), msp.getPos().X()); double probe_r = sqrt(pow(msp.getPos().X(), 2) + pow(msp.getPos().Y(), 2)); @@ -1466,109 +1203,51 @@ class ForwardTrackMaker { double h_phi = TMath::ATan2(h->getY(), h->getX()); double h_r = sqrt(pow(h->getX(), 2) + pow(h->getY(), 2)); double mdphi = fabs(h_phi - probe_phi); - if (mdphi > 2*3.1415926) - mdphi = mdphi - 2*3.1415926; - + if ( mdphi < dphi && fabs( h_r - probe_r ) < dr) { // handle 2pi edge found_hits.push_back(h); } } return found_hits; - } // findFstHitsNearProjectedState - - /** - * @brief Finds FTT hits near projected state - * - * @param available_hits : FTT hits to consider - * @param msp : measured state on plane from existing track fit projection - * @param dx : search distance in x - * @param dy : search distance in y - * - * @return compatible FTT hits - */ - Seed_t findFttHitsNearProjectedState(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dx = 1.5, double dy = 1.5) { - - Seed_t found_hits; - TLorentzVector lv1, lv2; - lv1.SetPxPyPzE( msp.getPos().X(), msp.getPos().Y(), 0, 1 ); - - double mindx = 99; - double mindy = 99; - double mindr = 99; - double mindp = 99; - KiTrack::IHit *closest = nullptr; - - for (auto h : available_hits) { - - lv2.SetPxPyPzE( h->getX(), h->getY(), 0, 1 ); - double sr = lv1.Pt() - lv2.Pt(); - double sp = lv1.DeltaPhi( lv2 ); - double sx = h->getX() - msp.getPos().X(); - double sy = h->getY() - msp.getPos().Y(); - - if ( fabs(sr) < fabs(mindr) ) - mindr = sr; - if ( fabs(sp) < fabs(mindp) ){ - mindp = sp; - closest = h; - } - if ( fabs(sx) < fabs(mindx) ) - mindx = sx; - if ( fabs(sy) < fabs(mindy) ) - mindy = sy; - - } // loop h - - if ( fabs(mindp) < 0.04*5 && fabs(mindr) < 9 ) { - found_hits.push_back(closest); - } - - return found_hits; - } // findFttHitsNearProjectedState + } bool getSaveCriteriaValues() { return mSaveCriteriaValues; } std::vector getTwoHitCriteria() { return mTwoHitCrit; } std::vector getThreeHitCriteria() { return mThreeHitCrit; } TrackFitter *getTrackFitter() { return mTrackFitter; } - void setEventVertex( TVector3 v, TMatrixDSym cov ){ - mEventVertex = v; - // this is the FwdHit we will use in seeds - mEventVertexHit.setXYZDetId( v.X(), v.Y(), v.Z(), kTpcId ); - for (size_t i=0; i < 3; i++){ - for (size_t j=0; j < 3; j++){ - mEventVertexHit._covmat(i,j) = cov(i,j); - } - } - } - TVector3 getEventVertex() { return mEventVertex; } + void setEventVertex( TVector3 v ) { mEventVertex = v; } protected: unsigned long long int nEvents; bool mDoTrackFitting = true; - bool mSaveCriteriaValues = false; - enum SeedSource { kFstSeed = 0, kFttSeed, kSimSeed, kSeqSeed }; - int mSeedSource = 1; // 0 = FST, 1 = FTT, 2 = FST+FTT simultaneous, 3 = FST+FTT sequential + bool mSaveCriteriaValues = true; FwdTrackerConfig mConfig; std::string mConfigFile; size_t mTotalHitsRemoved; - + std::vector mTrackResults; - std::vector mTrackSeeds; // the tracks recod from all iterations - std::vector mTrackSeedsThisIteration; - - // Metrics about the event - EventStats mEventStats; + std::vector mRecoTracks; // the tracks recod from all iterations + std::vector mRecoTracksThisItertion; // Set to the Primary vertex for the event TVector3 mEventVertex; - FwdHit mEventVertexHit; - genfit::GFRaveVertexFactory mGFRVertices; - + + // These are vectors with info about each track / fit + // they should all have the same length + std::vector mRecoTrackQuality; + std::vector mRecoTrackIdTruth; + std::vector mFitMoms; + std::vector mNumFstHits; + std::vector mFitStatus; + std::vector mGlobalTrackReps; + std::vector mGlobalTracks; + + QualityPlotter *mQualityPlotter; std::shared_ptr mDataSource; TrackFitter *mTrackFitter = nullptr; @@ -1577,7 +1256,12 @@ class ForwardTrackMaker { std::vector mThreeHitCrit; // histograms of the raw input data + bool mGenHistograms = false; // controls these histograms and use of QualityPlotter TString mGeoCache; + std::map mHist; + + + }; #endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h b/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h index 675881ccd50..623b0172452 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h @@ -1,6 +1,4 @@ -#ifndef __OBJEXPORTER_H__ -#define __OBJEXPORTER_H__ #include "GenFit/FitStatus.h" #include "GenFit/GFRaveVertexFactory.h" #include @@ -53,20 +51,20 @@ class ObjExporter { numVertices++; } } - + //## OUTPUT FACES BETWEEN INTERMEDIATE POINTS: - + for(p=1; pquadrant() == kFttQuadrantA ){ mx = 0; my = 0; sx = 1.0; sy = 1.0; @@ -250,13 +249,13 @@ class ObjExporter { } } } // ftt_strips - + // Output the event info into a useful format for event display - void output( std::string filename, + void output( std::string filename, StEvent * event, - std::vector< Seed_t> seeds, - std::vector< genfit::Track *> tracks, - const std::vector< genfit::GFRaveVertex *> &vertices, + std::vector< Seed_t> seeds, + std::vector< genfit::Track *> tracks, + const std::vector< genfit::GFRaveVertex *> &vertices, std::vector &fttHits, std::vector &fstHits, std::vector &fcsPreHits, // EPD = preshower @@ -307,9 +306,9 @@ class ObjExporter { ofile << "o fstHits" << endl; ofile << "usemtl fst_hits\n" << endl; for ( auto p : fstHits ){ - - // float fstphi = TMath::ATan2( p.Y(), p.X() ); - // printf( "FST PHI: %f \n", fstphi ); + + float fstphi = TMath::ATan2( p.Y(), p.X() ); + printf( "FST PHI: %f \n", fstphi ); // tri( ofile, TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.1f, 0.1f, 3.0f, fstphi ); sphere( TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.3, 10, 10, ofile ); } @@ -319,12 +318,12 @@ class ObjExporter { if (verbose){ LOG_INFO << "Viz has " << fcsPreHits.size() << " EPD Hits" << endm; } - if ( fcsPreHits.size() > 0 ){ + if ( fcsPreHits.size() > 0 ){ ofile << "\n" << endl; ofile << "o epd" << endl; ofile << "usemtl fcs_hits\n" << endl; for ( auto p : fcsPreHits ){ - + sphere( TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.25, 10, 10, ofile ); } } @@ -332,7 +331,7 @@ class ObjExporter { if (verbose){ LOG_INFO << "Viz has " << fcsClusters.size() << " FCS Hits" << endm; } - if ( fcsClusters.size() > 0 ){ + if ( fcsClusters.size() > 0 ){ ofile << "\n" << endl; ofile << "o fcs" << endl; ofile << "usemtl fcs_hits\n" << endl; @@ -344,7 +343,7 @@ class ObjExporter { i++; } } - + // Write the track seeds if (verbose){ LOG_INFO << "Viz has " << seeds.size() << " seeds" << endm; @@ -363,7 +362,7 @@ class ObjExporter { ofile << "l "; for ( size_t i = vStart; i < numVertices; i++){ - ofile << i+1 << " "; + ofile << i+1 << " "; } ofile << endl; } @@ -383,8 +382,8 @@ class ObjExporter { float zStep = 5.0; // cm for ( auto t : tracks ) { size_t vStart = numVertices; - - + + TVector3 lpoint; for ( float z = startPos.Z(); z < 875; z += zStep ){ TVector3 point = trackPosition( t, z ); @@ -394,21 +393,18 @@ class ObjExporter { vert( ofile, point.X() * SCALE, point.Y() * SCALE, -point.Z() * SCALE ); lpoint = point; } - + ofile << "l "; for ( size_t i = vStart; i < numVertices; i++){ - ofile << i+1 << " "; + ofile << i+1 << " "; } ofile << endl; } // for t in tracks } // if tracks.size() > 0 - ofile.close(); + ofile.close(); } size_t numVertices; }; - - -#endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h b/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h index 928a3e933ef..de55a2a53e1 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h @@ -8,6 +8,20 @@ #include "GenFit/KalmanFitStatus.h" #include "GenFit/GblFitter.h" +#include "GenFit/KalmanFitter.h" +#include "GenFit/KalmanFitterInfo.h" +#include "GenFit/KalmanFitterRefTrack.h" +#include "GenFit/MaterialEffects.h" +#include "GenFit/PlanarMeasurement.h" +#include "GenFit/RKTrackRep.h" +#include "GenFit/SpacepointMeasurement.h" +#include "GenFit/StateOnPlane.h" +#include "GenFit/TGeoMaterialInterface.h" +#include "GenFit/Track.h" +#include "GenFit/TrackPoint.h" + +#include "Criteria/SimpleCircle.h" + #include "TDatabasePDG.h" #include "TGeoManager.h" #include "TMath.h" @@ -26,35 +40,29 @@ #include "StFwdTrackMaker/include/Tracker/FwdGeomUtils.h" #include "StarGenerator/UTIL/StarRandom.h" -#include "FitterUtils.h" -/* Class for interfacing with GenFit for fitting tracks +/* Cass for fitting tracks(space points) with GenFit * */ class TrackFitter { // Accessors and options public: - std::shared_ptr getTrack() { return mFitTrack; } + genfit::FitStatus getStatus() { return mFitStatus; } + genfit::AbsTrackRep *getTrackRep() { return mTrackRep; } + genfit::Track *getTrack() { return mFitTrack; } + void setGenerateHistograms( bool gen) { mGenHistograms = gen;} + public: + // ctor + // provide the main configuration object + TrackFitter(FwdTrackerConfig _mConfig, TString geoCache) : mConfig(_mConfig), mGeoCache(geoCache) { + mTrackRep = 0; + mFitTrack = 0; + } + - /** - * @brief Construct a new Track Fitter object - * - * @param _mConfig : Config object - * @param geoCache : Geometry cache filename - */ - TrackFitter(FwdTrackerConfig _mConfig, TString geoCache) : mConfig(_mConfig), mGeoCache(geoCache), mFitTrack(nullptr) {} - - /** - * @brief Setup the tracker object - * Load geometry - * Setup Material Effects - * Setup the magnetic field - * Setup the fitter - * Setup the fit planes - */ void setup() { // the geometry manager that GenFit will use @@ -69,62 +77,56 @@ class TrackFitter { // Set Material Stepper debug level genfit::MaterialEffects::getInstance()->setDebugLvl( mConfig.get("TrackFitter.MaterialEffects:DebugLvl", 0) ); - + genfit::MaterialEffects::getInstance()->setEnergyLossBetheBloch( mConfig.get("TrackFitter.MaterialEffects.EnergyLossBetheBloch", true) ); genfit::MaterialEffects::getInstance()->setNoiseBetheBloch( mConfig.get("TrackFitter.MaterialEffects.NoiseBetheBloch", true) ); genfit::MaterialEffects::getInstance()->setNoiseCoulomb( mConfig.get("TrackFitter.MaterialEffects.NoiseCoulomb", true) ); genfit::MaterialEffects::getInstance()->setEnergyLossBrems( mConfig.get("TrackFitter.MaterialEffects.EnergyLossBrems", true) ); genfit::MaterialEffects::getInstance()->setNoiseBrems( mConfig.get("TrackFitter.MaterialEffects.NoiseBrems", true) ); genfit::MaterialEffects::getInstance()->ignoreBoundariesBetweenEqualMaterials( mConfig.get("TrackFitter.MaterialEffects.ignoreBoundariesBetweenEqualMaterials", true) ); - + // do this last to override genfit::MaterialEffects::getInstance()->setNoEffects( !mConfig.get("TrackFitter:MaterialEffects", false)); // negated, true means defaul is all effects on (noEffects off) if (!mConfig.get("TrackFitter:MaterialEffects", false)){ LOG_INFO << "Turning OFF GenFit Material Effects in stepper" << endm; } - + // Determine which Magnetic field to use // Either constant field or real field from StarFieldAdaptor if (mConfig.get("TrackFitter:constB", false)) { - mBField = std::unique_ptr(new genfit::ConstField(0., 0., 5.0)); // 0.5 T Bz - LOG_INFO << "StFwdTrackMaker: Tracking with constant magnetic field" << endm; + mBField = std::unique_ptr(new genfit::ConstField(0., 0., 5.)); // 0.5 T Bz + LOG_INFO << "StFwdTrackMaker: Tracking with constant magnetic field" << endl; } else if (mConfig.get("TrackFitter:zeroB", false)) { mBField = std::unique_ptr(new genfit::ConstField(0., 0., 0.)); // ZERO FIELD - LOG_INFO << "StFwdTrackMaker: Tracking with ZERO magnetic field" << endm; + LOG_INFO << "StFwdTrackMaker: Tracking with ZERO magnetic field" << endl; } else { mBField = std::unique_ptr(new StarFieldAdaptor()); - LOG_INFO << "StFwdTrackMaker: Tracking with StarFieldAdapter" << endm; + LOG_INFO << "StFwdTrackMaker: Tracking with StarFieldAdapter" << endl; } // we must have one of the two available fields at this point // note, the pointer is still bound to the lifetime of the TackFitter - genfit::FieldManager::getInstance()->init(mBField.get()); + genfit::FieldManager::getInstance()->init(mBField.get()); // initialize the main mFitter using a KalmanFitter with reference tracks mFitter = std::unique_ptr(new genfit::KalmanFitterRefTrack()); - // Here we load several options from the config, + // Here we load several options from the config, // to customize the mFitter behavior mFitter->setMaxFailedHits(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxFailedHits", -1)); // default -1, no limit mFitter->setDebugLvl(mConfig.get("TrackFitter.KalmanFitterRefTrack:DebugLvl", 0)); // default 0, no output - mFitter->setMaxIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxIterations", 40)); // default 4 iterations + mFitter->setMaxIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxIterations", 4)); // default 4 iterations mFitter->setMinIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MinIterations", 0)); // default 0 iterations - // Set the fit convergence paramters - mFitter->setRelChi2Change( mConfig.get("TrackFitter.KalmanFitterRefTrack:RelChi2Change", 1e-3) ); - // mFitter->setAbsChi2Change( mConfig.get("TrackFitter.KalmanFitterRefTrack:AbsChi2Change", 1e-3) ); - mFitter->setDeltaPval( mConfig.get("TrackFitter.KalmanFitterRefTrack:DeltaPval", 1e-3) ); - mFitter->setBlowUpFactor( mConfig.get("TrackFitter.KalmanFitterRefTrack:BlowUpFactor", 1e3) ); - // FwdGeomUtils looks into the loaded geometry and gets detector z locations if present FwdGeomUtils fwdGeoUtils( gMan ); - // these default values are the default if the detector is - // a) not found in the geometry + // these default values are the default if the detector is + // a) not found in the geometry // b) not provided in config // NOTE: these defaults are needed since the geometry file might not include FST (bug being worked on separately) mFSTZLocations = fwdGeoUtils.fstZ( - mConfig.getVector("TrackFitter.Geometry:fst", + mConfig.getVector("TrackFitter.Geometry:fst", {140.286011, 154.286011, 168.286011 } // 144.633,158.204,171.271 ) @@ -182,7 +184,7 @@ class TrackFitter { LOG_DEBUG << sstr.str() << endm; // Now load FTT - // mConfig.getVector<>(...) requires a default, hence the + // mConfig.getVector<>(...) requires a default, hence the mFTTZLocations = fwdGeoUtils.fttZ( mConfig.getVector("TrackFitter.Geometry:ftt", {281.082,304.062,325.058,348.068}) ); @@ -210,19 +212,242 @@ class TrackFitter { delim = ", "; } LOG_DEBUG << sstr.str() << endm; + + // get default vertex values used in simulation from the config + mVertexSigmaXY = mConfig.get("TrackFitter.Vertex:sigmaXY", 1.0); + mVertexSigmaZ = mConfig.get("TrackFitter.Vertex:sigmaZ", 30.0); + mVertexPos = mConfig.getVector("TrackFitter.Vertex:pos", {0.0,0.0,0.0}); + mIncludeVertexInFit = mConfig.get("TrackFitter.Vertex:includeInFit", false); + + if ( mGenHistograms ) + makeHistograms(); } - /** - * @brief Get the Fst Plane object for a given hit - * - * @param h : hit - * @return genfit::SharedPlanePtr + void makeHistograms() { + std::string n = ""; + mHist["ECalProjPosXY"] = new TH2F("ECalProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); + mHist["ECalProjSigmaXY"] = new TH2F("ECalProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 50, 0, 0.5, 50, 0, 0.5); + mHist["ECalProjSigmaR"] = new TH1F("ECalProjSigmaR", ";#sigma_{XY} (cm) at ECAL", 50, 0, 0.5); + + mHist["SiProjPosXY"] = new TH2F("SiProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); + mHist["SiProjSigmaXY"] = new TH2F("SiProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 150, 0, 15, 150, 0, 15); + + mHist["VertexProjPosXY"] = new TH2F("VertexProjPosXY", ";X;Y", 100, -5, 5, 100, -5, 5); + mHist["VertexProjSigmaXY"] = new TH2F("VertexProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 150, 0, 20, 150, 0, 20); + + mHist["VertexProjPosZ"] = new TH1F("VertexProjPosZ", ";Z;", 100, -50, 50); + mHist["VertexProjSigmaZ"] = new TH1F("VertexProjSigmaZ", ";#sigma_{Z};", 100, 0, 10); + + mHist["SiWrongProjPosXY"] = new TH2F("SiWrongProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); + mHist["SiWrongProjSigmaXY"] = new TH2F("SiWrongProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 50, 0, 0.5, 50, 0, 0.5); + + mHist["SiDeltaProjPosXY"] = new TH2F("SiDeltaProjPosXY", ";X;Y", 1000, 0, 20, 1000, 0, 20); + + mHist["FstDiffZVsR"] = new TH2F( "FstDiffZVsR", ";R;dz", 400, 0, 40, 500, -5, 5 ); + mHist["FstDiffZVsPhiSliceInner"] = new TH2F( "FstDiffZVsPhiSliceInner", ";slice;dz", 15, 0, 15, 500, -5, 5 ); + mHist["FstDiffZVsPhiSliceOuter"] = new TH2F( "FstDiffZVsPhiSliceOuter", ";slice;dz", 15, 0, 15, 500, -5, 5 ); + + mHist["FstDiffZVsPhiOuter"] = new TH2F( "FstDiffZVsPhiOuter", ";slice;dz", 628, 0, TMath::Pi()*2, 500, -5, 5 ); + + mHist["CorrFstDiffZVsPhiSliceInner"] = new TH2F( "CorrFstDiffZVsPhiSliceInner", ";slice;dz", 15, 0, 15, 500, -5, 5 ); + mHist["CorrFstDiffZVsPhiSliceOuter"] = new TH2F( "CorrFstDiffZVsPhiSliceOuter", ";slice;dz", 15, 0, 15, 500, -5, 5 ); + + + n = "seed_curv"; + mHist[n] = new TH1F(n.c_str(), ";curv", 1000, 0, 10000); + n = "seed_pT"; + mHist[n] = new TH1F(n.c_str(), ";pT (GeV/c)", 500, 0, 10); + n = "seed_eta"; + mHist[n] = new TH1F(n.c_str(), ";eta", 500, 0, 5); + + n = "delta_fit_seed_pT"; + mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) pT (GeV/c)", 500, -5, 5); + n = "delta_fit_seed_eta"; + mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) eta", 500, 0, 5); + n = "delta_fit_seed_phi"; + mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) phi", 500, -5, 5); + + n = "FitStatus"; + mHist[n] = new TH1F(n.c_str(), ";", 5, 0, 5); + FwdTrackerUtils::labelAxis(mHist[n]->GetXaxis(), {"Total", "Pass", "Fail", "GoodCardinal", "Exception"}); + + n = "FitDuration"; + mHist[n] = new TH1F(n.c_str(), "; Duraton (ms)", 5000, 0, 50000); + + n = "FailedFitDuration"; + mHist[n] = new TH1F(n.c_str(), "; Duraton (ms)", 500, 0, 50000); + } + + // writes mHistograms stored in map only if mGenHistograms is true + void writeHistograms() { + if ( !mGenHistograms ) + return; + for (auto nh : mHist) { + nh.second->SetDirectory(gDirectory); + nh.second->Write(); + } + } + + /* Convert the 3x3 covmat to 2x2 by dropping z + * + */ + TMatrixDSym CovMatPlane(KiTrack::IHit *h){ + TMatrixDSym cm(2); + cm(0, 0) = static_cast(h)->_covmat(0, 0); + cm(1, 1) = static_cast(h)->_covmat(1, 1); + cm(0, 1) = static_cast(h)->_covmat(0, 1); + return cm; + } + + + /* FitSimpleCircle + * Used to determine a seed transverse momentum based on space points + * Takes a list of space points KiTrack::IHit * + * Takes three indecise used to lookup three of the possible hits within the list + */ + float fitSimpleCircle(Seed_t trackCand, size_t i0, size_t i1, size_t i2) { + float curv = 0; + + // ensure that no index is outside of range for FST or FTT volumes + if (i0 > 12 || i1 > 12 || i2 > 12) + return 0; + + try { + KiTrack::SimpleCircle sc(trackCand[i0]->getX(), trackCand[i0]->getY(), trackCand[i1]->getX(), trackCand[i1]->getY(), trackCand[i2]->getX(), trackCand[i2]->getY()); + curv = sc.getRadius(); + } catch (KiTrack::InvalidParameter &e) { + // if we got here we failed to get a valid seed. We will still try to move forward but the fit will probably fail + } + + // make sure the curv is valid + if (isinf(curv)) + curv = 999999.9; + + return curv; + } + + /* seedState + * Determines the seed position and momentum for a list of space points */ + float seedState(Seed_t trackCand, TVector3 &seedPos, TVector3 &seedMom) { + // we require at least 4 hits, so this should be gauranteed + if(trackCand.size() < 3){ + // failure + return 0.0; + } + + + // we want to use the LAST 3 hits, since silicon doesnt have R information + TVector3 p0, p1, p2; + // use the closest hit to the interaction point for the seed pos + FwdHit *hit_closest_to_IP = static_cast(trackCand[0]); + + // maps from to + std::map vol_map; + + // init the map + for (size_t i = 0; i < 13; i++) + vol_map[i] = -1; + + for (size_t i = 0; i < trackCand.size(); i++) { + auto fwdHit = static_cast(trackCand[i]); + vol_map[abs(fwdHit->_vid)] = i; + // find the hit closest to IP for the initial position seed + if (hit_closest_to_IP->getZ() > fwdHit->getZ()) + hit_closest_to_IP = fwdHit; + } + + // now get an estimate of the pT from several overlapping simple circle fits + // enumerate the available partitions + // 12 11 10 + // 12 11 9 + // 12 10 9 + // 11 10 9 + vector curvs; + curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[11], vol_map[10])); + curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[11], vol_map[9])); + curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[10], vol_map[9])); + curvs.push_back(fitSimpleCircle(trackCand, vol_map[11], vol_map[10], vol_map[9])); + + // average them and exclude failed fits + float mcurv = 0; + float nmeas = 0; + + for (size_t i = 0; i < curvs.size(); i++) { + if (mGenHistograms) + this->mHist["seed_curv"]->Fill(curvs[i]); + if (curvs[i] > 10) { + mcurv += curvs[i]; + nmeas += 1.0; + } + } + + if (nmeas >= 1) + mcurv = mcurv / nmeas; + else + mcurv = 10; + + // Now lets get eta information + // simpler, use farthest points from IP + if (vol_map[9] < 13) + p0.SetXYZ(trackCand[vol_map[9]]->getX(), trackCand[vol_map[9]]->getY(), trackCand[vol_map[9]]->getZ()); + + if (vol_map[10] < 13) + p1.SetXYZ(trackCand[vol_map[10]]->getX(), trackCand[vol_map[10]]->getY(), trackCand[vol_map[10]]->getZ()); + + const double K = 0.00029979; //K depends on the units used for Bfield + double pt = mcurv * K * 5; // pT from average measured curv + double dx = (p1.X() - p0.X()); + double dy = (p1.Y() - p0.Y()); + double dz = (p1.Z() - p0.Z()); + double phi = TMath::ATan2(dy, dx); + double Rxy = sqrt(dx * dx + dy * dy); + double theta = TMath::ATan2(Rxy, dz); + // double eta = -log( tantheta / 2.0 ); + // these starting conditions can probably be improvd, good study for student + + seedMom.SetPtThetaPhi(pt, theta, phi); + seedPos.SetXYZ(hit_closest_to_IP->getX(), hit_closest_to_IP->getY(), hit_closest_to_IP->getZ()); + + if (mGenHistograms) { + this->mHist["seed_pT"]->Fill(seedMom.Pt()); + this->mHist["seed_eta"]->Fill(seedMom.Eta()); + } + + return mcurv; + } + + + genfit::MeasuredStateOnPlane projectToFst(size_t si_plane, genfit::Track *fitTrack) { + if (si_plane > 2) { + genfit::MeasuredStateOnPlane nil; + return nil; + } + + auto detSi = mFSTPlanes[si_plane]; + genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); + auto TCM = fitTrack->getCardinalRep()->get6DCov(tst); + + // this returns the track length if needed + fitTrack->getCardinalRep()->extrapolateToPlane(tst, detSi); + + TCM = fitTrack->getCardinalRep()->get6DCov(tst); + + // can get the projected positions if needed + float x = tst.getPos().X(); + float y = tst.getPos().Y(); + float z = tst.getPos().Z(); + // and the uncertainties + LOG_DEBUG << "Track Uncertainty at FST (plane=" << si_plane << ") @ x= " << x << ", y= " << y << ", z= " << z << " : " << sqrt(TCM(0, 0)) << ", " << sqrt(TCM(1, 1)) << endm; + + return tst; + } + genfit::SharedPlanePtr getFstPlane( FwdHit * h ){ size_t planeId = h->getSector(); - const TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); + TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); double phi = hitXYZ.Phi(); if ( phi < 0 ) phi = TMath::Pi() * 2 + phi; @@ -242,99 +467,344 @@ class TrackFitter { } return planeCorr; - } // GetFST PLANE - /** - * @brief Convert the 3x3 covmat to 2x2 by dropping z - * - * @param h : hit with cov matrix - * @return TMatrixDSym : cov matrix 2x2 - */ - TMatrixDSym CovMatPlane(KiTrack::IHit *h){ - TMatrixDSym cm(2); - cm(0, 0) = static_cast(h)->_covmat(0, 0); - cm(1, 1) = static_cast(h)->_covmat(1, 1); - cm(0, 1) = static_cast(h)->_covmat(0, 1); - return cm; } + /* RefitTracksWithSiHits + * Takes a previously fit track re-fits it with the newly added silicon hits + * + */ + TVector3 refitTrackWithSiHits(genfit::Track *originalTrack, Seed_t si_hits) { + // mem leak, global track is overwritten without delete. + TVector3 pOrig = originalTrack->getCardinalRep()->getMom(originalTrack->getFittedState(1, originalTrack->getCardinalRep())); + + // auto cardinalStatus = originalTrack->getFitStatus(originalTrack->getCardinalRep()); + + if (originalTrack->getFitStatus(originalTrack->getCardinalRep())->isFitConverged() == false) { + // in this case the original track did not converge so we should not refit. + // probably never get here due to previous checks + return pOrig; + } + + // Setup the Track Reps + auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); + auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); + + // get the space points on the original track + auto trackPoints = originalTrack->getPointsWithMeasurement(); + + if ((trackPoints.size() < (mFTTZLocations.size() +1) && mIncludeVertexInFit) || trackPoints.size() < mFTTZLocations.size() ) { + // we didnt get enough points for a refit + return pOrig; + } + + TVectorD rawCoords = trackPoints[0]->getRawMeasurement()->getRawHitCoords(); + double z = mFSTZLocations[0]; //first FTT plane, used if we dont have PV in fit + if (mIncludeVertexInFit) + z = rawCoords(2); + + TVector3 seedPos(rawCoords(0), rawCoords(1), z); + TVector3 seedMom = pOrig; + + // Create the ref track using the seed state + auto mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); + mFitTrack->addTrackRep(trackRepNeg); + + genfit::Track &fitTrack = *mFitTrack; + + size_t firstFTTIndex = 0; + if (mIncludeVertexInFit) { + // clone the PRIMARY VERTEX into this track + fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[0]->getRawMeasurement(), &fitTrack)); + firstFTTIndex = 1; // start on hit index 1 below + } + + // initialize the hit coords on plane + TVectorD hitCoords(2); + hitCoords[0] = 0; + hitCoords[1] = 0; + + size_t planeId(0); + int hitId(5); + + // add the hits to the track + for (auto h : si_hits) { + if ( nullptr == h ) continue; // if no Si hit in this plane, skip + + hitCoords[0] = h->getX(); + hitCoords[1] = h->getY(); + genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), h->getSector(), ++hitId, nullptr); + + planeId = h->getSector(); + + if (mFSTPlanes.size() <= planeId) { + LOG_WARN << "invalid VolumId -> out of bounds DetPlane, vid = " << planeId << endm; + return pOrig; + } + + // auto plane = mFSTPlanes[planeId]; + auto plane = getFstPlane( static_cast(h) ); + + measurement->setPlane(plane, planeId); + fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); + + + TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); + float phi = hitXYZ.Phi(); + if ( phi < 0 ) phi = TMath::Pi() * 2 + phi; + double phi_slice = phi / (TMath::Pi() / 6.0); // 2pi/12 + int phi_index = ((int)phi_slice); + double dz = (h->getZ() - plane->getO().Z()); + + double r =sqrt( pow(hitXYZ.x(), 2) + pow(hitXYZ.y(), 2) ); + + size_t idx = phi_index % 2; + auto planeCorr = mFSTPlanesInner[planeId + idx]; + if ( r > 16 ){ + planeCorr = mFSTPlanesOuter[planeId + idx]; + } + double cdz = (h->getZ() - planeCorr->getO().Z()); + + if (mGenHistograms){ + + ((TH2*)mHist[ "FstDiffZVsR" ])->Fill( r, dz ); + + if ( r < 16 ) {// inner + mHist["FstDiffZVsPhiSliceInner"]->Fill( phi_slice, dz ); + mHist["CorrFstDiffZVsPhiSliceInner"]->Fill( phi_slice, cdz ); + } else { + mHist["FstDiffZVsPhiSliceOuter"]->Fill( phi_slice, dz ); + mHist["CorrFstDiffZVsPhiSliceOuter"]->Fill( phi_slice, cdz ); + mHist["FstDiffZVsPhiOuter"]->Fill( phi, dz ); + } + } + // mHist[ "FstDiffZVsPhiSliceInner" ]->Fill( sqrt( pow(hitXYZ.x(), 2), pow(hitXYZ.y(), 2) ), dz ); + + } + // start at 0 if PV not included, 1 otherwise + for (size_t i = firstFTTIndex; i < trackPoints.size(); i++) { + // clone the track points into this track + fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[i]->getRawMeasurement(), &fitTrack)); + } + + try { + //Track RE-Fit with GENFIT2 + // check consistency of all points + fitTrack.checkConsistency(); + + // do the actual track fit + mFitter->processTrack(&fitTrack); - /** - * @brief Get projection to given FST plane + fitTrack.checkConsistency(); + + // this chooses the lowest chi2 fit result as cardinal + fitTrack.determineCardinalRep(); + + } catch (genfit::Exception &e) { + // will be caught below by converge check + LOG_WARN << "Track fit exception : " << e.what() << endm; + } + + if (fitTrack.getFitStatus(fitTrack.getCardinalRep())->isFitConverged() == false) { + // Did not converge + return pOrig; + } else { // we did converge, return new momentum + + try { + // causes seg fault + auto cardinalRep = fitTrack.getCardinalRep(); + auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); + mFitStatus = *cardinalStatus; // save the status of last fit + } catch (genfit::Exception &e) { + } + + TVector3 p = fitTrack.getCardinalRep()->getMom(fitTrack.getFittedState(1, fitTrack.getCardinalRep())); + return p; + } + return pOrig; + } // refit with Si hits + + TVector3 refitTrackWithGBL( genfit::Track *originalTrack ) { + // mem leak, global track is overwritten without delete. + TVector3 pOrig = originalTrack->getCardinalRep()->getMom(originalTrack->getFittedState(1, originalTrack->getCardinalRep())); + + // auto cardinalStatus = originalTrack->getFitStatus(originalTrack->getCardinalRep()); + + if (originalTrack->getFitStatus(originalTrack->getCardinalRep())->isFitConverged() == false) { + // in this case the original track did not converge so we should not refit. + // probably never get here due to previous checks + return pOrig; + } + + // Setup the Track Reps + auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); + auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); + + // get the space points on the original track + auto trackPoints = originalTrack->getPointsWithMeasurement(); + + + TVectorD rawCoords = trackPoints[0]->getRawMeasurement()->getRawHitCoords(); + TVector3 seedPos(rawCoords(0), rawCoords(1), rawCoords(2)); + TVector3 seedMom = pOrig; + + // Create the ref track using the seed state + auto pFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); + pFitTrack->addTrackRep(trackRepNeg); + + genfit::Track &fitTrack = *pFitTrack; + + for (size_t i = 0; i < trackPoints.size(); i++) { + // clone the track points into this track + fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[i]->getRawMeasurement(), &fitTrack)); + } + + auto gblFitter = std::unique_ptr(new genfit::GblFitter()); + try { + // check consistency of all points + fitTrack.checkConsistency(); + + // do the actual track fit + mFitter->processTrack(&fitTrack); + + fitTrack.checkConsistency(); + + // this chooses the lowest chi2 fit result as cardinal + fitTrack.determineCardinalRep(); + + } catch (genfit::Exception &e) { + // will be caught below by converge check + LOG_WARN << "Track fit exception : " << e.what() << endm; + } + + if (fitTrack.getFitStatus(fitTrack.getCardinalRep())->isFitConverged() == false) { + LOG_WARN << "GBL fit did not converge" << endm; + delete pFitTrack; + return pOrig; + } else { // we did converge, return new momentum + + try { + // causes seg fault + auto cardinalRep = fitTrack.getCardinalRep(); + auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); + mFitStatus = *cardinalStatus; // save the status of last fit + } catch (genfit::Exception &e) { + LOG_WARN << "Failed to get cardinal status from converged fit" << endm; + } + auto mom = fitTrack.getCardinalRep()->getMom(fitTrack.getFittedState(1, fitTrack.getCardinalRep())); + delete pFitTrack; + return mom; + } + delete pFitTrack; + return pOrig; + } //refitwith GBL + + + + /* Generic method for fitting space points with GenFit * - * @param fstPlane : plane index - * @param fitTrack : track to project - * @return genfit::MeasuredStateOnPlane + * */ - genfit::MeasuredStateOnPlane projectToFst(size_t fstPlane, std::shared_ptr fitTrack) { - if (fstPlane > 2) { - genfit::MeasuredStateOnPlane nil; - return nil; + TVector3 fitSpacePoints( vector spoints, TVector3 &seedPos, TVector3 &seedMom ){ + + // setup track reps + auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); + auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); + + // setup track for fit with positive and negative reps + auto mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); + mFitTrack->addTrackRep(trackRepNeg); + + genfit::Track &fitTrack = *mFitTrack; + + // try adding the points to track and fitting + try { + for ( size_t i = 0; i < spoints.size(); i++ ){ + fitTrack.insertPoint(new genfit::TrackPoint(spoints[i], &fitTrack)); + } + // do the fit against the two possible fits + mFitter->processTrackWithRep(&fitTrack, trackRepPos); + mFitter->processTrackWithRep(&fitTrack, trackRepNeg); + + } catch (genfit::Exception &e) { + LOG_ERROR << "GenFit failed to fit track with: " << e.what() << endm; } - auto detFst = mFSTPlanes[fstPlane]; - // TODO: Why use 1 here? - genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); - // NOTE: this returns the track length if needed - fitTrack->getCardinalRep()->extrapolateToPlane(tst, detFst); + try { + fitTrack.checkConsistency(); - return tst; + fitTrack.determineCardinalRep(); + auto cardinalRep = fitTrack.getCardinalRep(); + + TVector3 p = cardinalRep->getMom(fitTrack.getFittedState(1, cardinalRep)); + // sucess, return momentum + return p; + } catch (genfit::Exception &e) { + LOG_ERROR << "GenFit failed to fit track with: " << e.what() << endm; + } + return TVector3(0, 0, 0); } - /** - * @brief Get projection to given FTT plane + /* Fit a track * - * @param fttPlane : plane index - * @param fitTrack : track to project - * @return genfit::MeasuredStateOnPlane + * */ - genfit::MeasuredStateOnPlane projectToFtt(size_t iFttPlane, std::shared_ptr fitTrack) { - if (iFttPlane > 3) { - genfit::MeasuredStateOnPlane nil; - return nil; + TVector3 fitTrack(Seed_t trackCand, double *Vertex = 0, TVector3 *McSeedMom = 0) { + long long itStart = FwdTrackerUtils::nowNanoSecond(); + if (mGenHistograms) this->mHist["FitStatus"]->Fill("Total", 1); + + // The PV information, if we want to use it + TVectorD pv(3); + + StarRandom rand = StarRandom::Instance(); + if (0 == Vertex) { // randomized from simulation + pv[0] = mVertexPos[0] + rand.gauss(mVertexSigmaXY); + pv[1] = mVertexPos[1] + rand.gauss(mVertexSigmaXY); + pv[2] = mVertexPos[2] + rand.gauss(mVertexSigmaZ); + } else { + pv[0] = Vertex[0]; + pv[1] = Vertex[1]; + pv[2] = Vertex[2]; } - auto fttPlane = mFTTPlanes[iFttPlane]; - // TODO: why use 1 here? - genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); - // NOTE: this returns the track length if needed - fitTrack->getCardinalRep()->extrapolateToPlane(tst, fttPlane); - return tst; - } - /** - * @brief setup the track from the given seed and optional primary vertex - * @param trackSeed : seed points - * @param seedMom : seed momentum - * @param seedPos : seed position - * @param Vertex : primary vertex - */ - void setupTrack(Seed_t trackSeed ) { - - // setup the track fit seed parameters - GenericFitSeeder gfs; - int seedQ = 1; - TVector3 seedPos(0, 0, 0); - TVector3 seedMom(0, 0, 10); // this default seed actually works better than a half-bad guess - gfs.makeSeed( trackSeed, seedPos, seedMom, seedQ ); - LOG_DEBUG << "Setting track fit seed position = " << TString::Format( "(%f, %f, %f)", seedPos.X(), seedPos.Y(), seedPos.Z() ) << endm; - LOG_DEBUG << "Setting track fit seed momentum = " << TString::Format( "(%f, %f, %f)", seedMom.X(), seedMom.Y(), seedMom.Z() ) << endm; - if ( seedMom.Perp() > 0.001 ){ - // because ROOT has an assert in there :/ - LOG_DEBUG << "Setting track fit seed momentum = (Pt,eta,phi)=" << TString::Format( "(%f, %f, %f)", seedMom.Pt(), seedMom.Eta(), seedMom.Phi() ) << endm; + // get the seed info from our hits + TVector3 seedMom, seedPos; + // returns track curvature if needed + seedState(trackCand, seedPos, seedMom); + + if (McSeedMom != nullptr) { + seedMom = *McSeedMom; + } + + // If we use the PV, use that as the start pos for the track + if (mIncludeVertexInFit) { + LOG_DEBUG << "Primary Vertex in fit (seed pos) @ " << TString::Format( "(%f, %f, %f)", pv[0], pv[1], pv[2] ).Data() << endm; + seedPos.SetXYZ(pv[0], pv[1], pv[2]); + } + + if (mFitTrack){ + delete mFitTrack; } - - LOG_DEBUG << "Setting track fit seed charge = " << seedQ << endm; // create the track representations - // Note that multiple track reps differing only by charge results in a silent failure of GenFit - auto theTrackRep = new genfit::RKTrackRep(mPdgMuon * -1 * seedQ); // bc pos PDG codes are for neg particles + auto trackRepPos = new genfit::RKTrackRep(mPdgMuon); + auto trackRepNeg = new genfit::RKTrackRep(mPdgAntiMuon); // Create the track - mFitTrack = std::make_shared(theTrackRep, seedPos, seedMom); - // now add the points to the track + mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); + mFitTrack->addTrackRep(trackRepNeg); + + + LOG_DEBUG + << "seedPos : (" << seedPos.X() << ", " << seedPos.Y() << ", " << seedPos.Z() << " )" + << ", seedMom : (" << seedMom.X() << ", " << seedMom.Y() << ", " << seedMom.Z() << " )" + << ", seedMom : (" << seedMom.Pt() << ", " << seedMom.Eta() << ", " << seedMom.Phi() << " )" + << endm; + + genfit::Track &fitTrack = *mFitTrack; - int hitId(0); // hit ID size_t planeId(0); // detector plane ID + int hitId(0); // hit ID // initialize the hit coords on plane TVectorD hitCoords(2); @@ -342,164 +812,132 @@ class TrackFitter { hitCoords[1] = 0; /****************************************************************************************************************** - * loop over the hits, add them to the track - ******************************************************************************************************************/ - // use these to enforce our sorting parameters - size_t idxFst = 0; // index of the FST hit - size_t idxFtt = 0; // index of the FTT hit - for (auto h : trackSeed) { - auto fh = dynamic_cast(h); - hitCoords[0] = h->getX(); - hitCoords[1] = h->getY(); + * Include the Primary vertex if desired + ******************************************************************************************************************/ + if (mIncludeVertexInFit) { - /****************************************************************************************************************** - * If the Primary vertex is included - ******************************************************************************************************************/ - if ( true ) { - LOG_INFO << "Treating hit as a spacepoint" << endm; - if ( fh->isPV() ){ - LOG_DEBUG << "Including primary vertex in fit" << endm; - } - TVectorD pv(3); - pv[0] = h->getX(); - pv[1] = h->getY(); - pv[2] = h->getZ(); - LOG_INFO << "x = " << pv[0] << "+/- " << fh->_covmat(0,0) << ", y = " << pv[1] << " +/- " << fh->_covmat(1,1) << ", z = " << pv[2] << " +/- " << fh->_covmat(2,2) << endm; - auto tp = new genfit::TrackPoint(); - genfit::SpacepointMeasurement *measurement = new genfit::SpacepointMeasurement(pv, fh->_covmat, fh->_detid, ++hitId, tp); - tp->addRawMeasurement(measurement); - tp->setTrack(mFitTrack.get()); - if ( fh->isPV() ){ - tp->setSortingParameter(0); - } - if ( fh->isFtt() ){ - tp->setSortingParameter(4 + idxFtt); - idxFtt++; - } - if ( fh->isFst() ){ - tp->setSortingParameter(1 + idxFst); - idxFst++; - } + TMatrixDSym hitCov3(3); + hitCov3(0, 0) = mVertexSigmaXY * mVertexSigmaXY; + hitCov3(1, 1) = mVertexSigmaXY * mVertexSigmaXY; + hitCov3(2, 2) = mVertexSigmaZ * mVertexSigmaZ; - mFitTrack->insertPoint( tp ); - continue; - } + genfit::SpacepointMeasurement *measurement = new genfit::SpacepointMeasurement(pv, hitCov3, 0, ++hitId, nullptr); + fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); + } - // if ( fh->isPV() ) continue; + /****************************************************************************************************************** + * loop over the hits, add them to the track + ******************************************************************************************************************/ + for (auto h : trackCand) { - genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), fh->_detid, ++hitId, nullptr); + hitCoords[0] = h->getX(); + hitCoords[1] = h->getY(); + + genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), h->getSector(), ++hitId, nullptr); planeId = h->getSector(); - genfit::SharedPlanePtr plane; - if ( fh->isFtt() ){ - planeId = fh->_vid - 9; - } - LOG_INFO << "planeId = " << planeId << ", sector " << h->getSector() << ", vid = " << fh->_vid << endm; - if (fh->isFtt() && mFTTPlanes.size() <= planeId) { - LOG_ERROR << "invalid VolumId -> out of bounds DetPlane, vid = " << dynamic_cast(h)->_vid << " vs. planeId = " << planeId << endm; - delete measurement; - continue; - } - if (fh->isFtt()) - plane = mFTTPlanes[planeId]; - else if (fh->isFst()) - plane = getFstPlane( fh ); + if (mFTTPlanes.size() <= planeId) { + LOG_WARN << "invalid VolumId -> out of bounds DetPlane, vid = " << planeId << endm; + return TVector3(0, 0, 0); + } + auto plane = mFTTPlanes[planeId]; measurement->setPlane(plane, planeId); - - mFitTrack->insertPoint(new genfit::TrackPoint(measurement, mFitTrack.get())); - LOG_INFO << "\tsetupTrack: Hit at Z = " << h->getZ() << " with plane at Z = " << plane->getO().Z() << endm; + fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); if (abs(h->getZ() - plane->getO().Z()) > 0.05) { LOG_WARN << "Z Mismatch h->z = " << h->getZ() << ", plane->z = "<< plane->getO().Z() <<", diff = " << abs(h->getZ() - plane->getO().Z()) << endm; } - } // loop on trackSeed - } // setupTrack + } // loop on trackCand + - /** @brief performs the fit on a track - * @param t : track to fit - */ - void performFit( std::shared_ptr t ){ /****************************************************************************************************************** * Do the fit ******************************************************************************************************************/ try { + // do the fit + mFitter->processTrackWithRep(&fitTrack, trackRepPos); + mFitter->processTrackWithRep(&fitTrack, trackRepNeg); - // prepare the track for fitting - // int nFailedPoints = 0; - // bool changed = false; - // changed = dynamic_cast( mFitter.get() )->prepareTrack( mFitTrack.get(), mFitTrack->getCardinalRep(), false, nFailedPoints); - // LOG_DEBUG << "Track prepared for fit with " << nFailedPoints << " failed points, changed? = " << changed << endm; + } catch (genfit::Exception &e) { + if (mGenHistograms) mHist["FitStatus"]->Fill("Exception", 1); + } - // check the track for consistency - mFitTrack->checkConsistency(); - // do the fit - mFitter->processTrack(t.get()); + TVector3 p(0, 0, 0); - // check the track for consistency - t->checkConsistency(); + /****************************************************************************************************************** + * Now check the fit + ******************************************************************************************************************/ + try { + //check + fitTrack.checkConsistency(); // find track rep with smallest chi2 - t->determineCardinalRep(); - // update the seed - // t->udpateSeed(); - - auto status = t->getFitStatus(); - LOG_INFO << "Fit status: " << status->isFitConverged() << endm; - LOG_INFO << "-Fit pvalue: " << status->getPVal() << endm; - LOG_INFO << "-Fit Chi2: " << status->getChi2() << endm; - - if ( status->isFitConverged() ){ - - auto cr = t->getCardinalRep(); - auto p = cr->getMom( t->getFittedState( 0, cr )); - int rcQ = status->getCharge(); - LOG_INFO << "Fit momentum: " << p.X() << ", " << p.Y() << ", " << p.Z() << endm; - LOG_INFO << "\tFit Pt: " << p.Pt() << ", eta: " << p.Eta() << ", phi: " << p.Phi() << endm; - // LOG_INFO << "\tMc Pt: " << mcMom.Pt() << ", eta: " << mcMom.Eta() << ", phi: " << mcMom.Phi() << endm; + fitTrack.determineCardinalRep(); + auto cardinalRep = fitTrack.getCardinalRep(); + auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); + mFitStatus = *cardinalStatus; // save the status of last fit + + // Delete any previous track rep + if (mTrackRep) + delete mTrackRep; + + // Clone the cardinal rep for persistency + mTrackRep = cardinalRep->clone(); // save the result of the fit + if (fitTrack.getFitStatus(cardinalRep)->isFitConverged() && mGenHistograms ) { + this->mHist["FitStatus"]->Fill("GoodCardinal", 1); } + if (fitTrack.getFitStatus(trackRepPos)->isFitConverged() == false && + fitTrack.getFitStatus(trackRepNeg)->isFitConverged() == false) { + + LOG_WARN << "FWD Track GenFit Failed" << endm; - } catch (genfit::Exception &e) { - LOG_ERROR << "Exception on fit update" << e.what() << endm; - } - LOG_INFO << "Track fit update complete!" << endm; - } + p.SetXYZ(0, 0, 0); + long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + if (mGenHistograms) { + this->mHist["FitStatus"]->Fill("Fail", 1); + this->mHist["FailedFitDuration"]->Fill(duration); + } + return p; + } // neither track rep converged - /** - * @brief Primary track fitting routine - * - * @param trackSeed : - * @param Vertex : Primary Vertex - * @param seedMomentum : seed momentum (can be from MC) - * @return void : the results can be accessed via the getTrack() method - */ - long long fitTrack(Seed_t trackSeed, TVector3 *seedMomentum = 0) { - long long itStart = FwdTrackerUtils::nowNanoSecond(); - LOG_DEBUG << "Fitting track with " << trackSeed.size() << " FWD Measurements" << endm; + p = cardinalRep->getMom(fitTrack.getFittedState(1, cardinalRep)); + mQ = cardinalRep->getCharge(fitTrack.getFittedState(1, cardinalRep)); + mP = p; - /****************************************************************************************************************** - * First sort the seed, bc GENFIT seemingly cannot handle out of order points - ******************************************************************************************************************/ - std::sort(trackSeed.begin(), trackSeed.end(), - [](KiTrack::IHit *a, KiTrack::IHit *b) - { return a->getZ() < b->getZ(); } - ); + LOG_DEBUG << "track fit p = " << TString::Format( "(%f, %f, %f), q=%f", p.X(), p.Y(), p.Z(), mQ ).Data() << endm; - /****************************************************************************************************************** - * Setup the track fit seed parameters and objects - ******************************************************************************************************************/ - setupTrack(trackSeed); - LOG_DEBUG << "Ready to fit with " << mFitTrack->getNumPoints() << " track points" << endm; + } catch (genfit::Exception &e) { + LOG_WARN << "Exception on track fit: " << e.what() << endm; + p.SetXYZ(0, 0, 0); + + long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + if (mGenHistograms) { + this->mHist["FitStatus"]->Fill("Exception", 1); + this->mHist["FailedFitDuration"]->Fill(duration); + } + + return p; + } // try/catch - /****************************************************************************************************************** - * Do the fit - ******************************************************************************************************************/ - performFit( mFitTrack ); long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - return duration; - } // fitTrack + if (mGenHistograms) { + this->mHist["FitStatus"]->Fill("Pass", 1); + this->mHist["delta_fit_seed_pT"]->Fill(p.Pt() - seedMom.Pt()); + this->mHist["delta_fit_seed_eta"]->Fill(p.Eta() - seedMom.Eta()); + this->mHist["delta_fit_seed_phi"]->Fill(p.Phi() - seedMom.Phi()); + this->mHist["FitDuration"]->Fill(duration); + } + return p; + } + + int getCharge() { + return (int)mQ; + } + + // Store the planes for FTT and FST vector mFTTPlanes; @@ -507,12 +945,18 @@ class TrackFitter { vector mFSTPlanesInner; vector mFSTPlanesOuter; + void SetIncludeVertex( bool vert ) { mIncludeVertexInFit = vert; } + protected: std::unique_ptr mBField; FwdTrackerConfig mConfig; // main config object TString mGeoCache; + // optional histograms, off by default + std::map mHist; + bool mGenHistograms = false; + // Main GenFit fitter instance std::unique_ptr mFitter = nullptr; @@ -528,8 +972,20 @@ class TrackFitter { // det z locations loaded from geom or config vector mFSTZLocations, mFTTZLocations; - // GenFit state - resused - std::shared_ptr mFitTrack; + // parameter ALIASED from mConfig wrt PV vertex + double mVertexSigmaXY = 1; + double mVertexSigmaZ = 30; + vector mVertexPos; + bool mIncludeVertexInFit = false; + + // GenFit state + genfit::FitStatus mFitStatus; + genfit::AbsTrackRep *mTrackRep; + genfit::Track *mFitTrack; + + // Fit results + TVector3 mP; + double mQ; }; #endif diff --git a/StRoot/StFwdTrackMaker/macro/build_geom.C b/StRoot/StFwdTrackMaker/macro/build_geom.C index 327c9af71eb..f0fd5663882 100755 --- a/StRoot/StFwdTrackMaker/macro/build_geom.C +++ b/StRoot/StFwdTrackMaker/macro/build_geom.C @@ -2,7 +2,7 @@ // that is a valid shebang to run script as executable -void build_geom( TString geomtag = "y2023", TString output="fGeom.root" ) { +void build_geom( TString geomtag = "dev2022", TString output="fGeom.root" ) { gSystem->Load( "libStarRoot.so" ); @@ -21,8 +21,7 @@ void build_geom( TString geomtag = "y2023", TString output="fGeom.root" ) { if ( 0 == geom ) { AgModule::SetStacker( new StarTGeoStacker() ); AgPosition::SetDebug(2); - cout << "Building geometry for tag [" << geomtag.Data() << "]" << endl; - StarGeometry::Construct( geomtag.Data() ); + StarGeometry::Construct("dev2022"); // Genfit requires the geometry is cached in a ROOT file gGeoManager->Export( output.Data() ); diff --git a/StRoot/StFwdTrackMaker/macro/daq/daq_track.C b/StRoot/StFwdTrackMaker/macro/daq/daq_track.C index c4bae46af5b..785b91ecbf5 100755 --- a/StRoot/StFwdTrackMaker/macro/daq/daq_track.C +++ b/StRoot/StFwdTrackMaker/macro/daq/daq_track.C @@ -1,79 +1,42 @@ //usr/bin/env root4star -l -b -q $0; exit $? // that is a valid shebang to run script as executable - -void daq_track( int n = 50, - const char *inFile = "st_fwd_23074018_raw_1000013.daq", - const char *geom = "y2023") { +void daq_track( int n = 10, + const char *inFile = "input.daq", + std::string configFile = "daq/daq_track.xml", + const char *geom = "dev2022") { TString _chain; gSystem->Load( "libStarRoot.so" ); // Simplest chain with fst, fcs, ftt and fwdTracker - _chain = Form("in, %s, db, StEvent, trgd, btof, fcs, fst, ftt, fwdTrack, fstMuRawHit, EventQA, CMuDst, evout, tree", geom); - // _chain = Form("in, %s, StEvent, fcs, fst, ftt, fwdTrack, evout, tree", geom); - - // needed in this wonky spack environment / docker container + _chain = Form("in, %s, db, StEvent, MuDST, fcs, fst, ftt, fwdTrack", geom); + + // needed in this wonky spack environment gROOT->SetMacroPath(".:/star-sw/StRoot/macros:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); gROOT->LoadMacro("bfc.C"); bfc(-1, _chain, inFile); - - StFttClusterMaker *fttClu = (StFttClusterMaker*) chain->GetMaker("stgcCluster"); - if (fttClu){ - // fttClu->SetDebug(2); - fttClu->SetTimeCut( 1, -40, 40); - } - - StMaker * fwdMakerGen = chain->GetMaker("fwdTrack"); - if ( fwdMakerGen ){ - // Extra configuration for the Forward Tracking - StFwdTrackMaker *fwdTrack = (StFwdTrackMaker*) chain->GetMaker("fwdTrack"); - if ( fwdTrack ){ //if it is in the chain - cout << "Setting up Fwd Tracking in chain" << endl; - // fwdTrack->SetConfigFile( configFile ); - fwdTrack->setConfigForData(); - fwdTrack->setZeroB(); - fwdTrack->setSeedFindingWithFst(); - // write out wavefront OBJ files - fwdTrack->SetVisualize( false ); - fwdTrack->SetDebug(2); - fwdTrack->setTrackRefit(true); - fwdTrack->setGeoCache( "fGeom.root" ); - // fwdTrack->setDebug(); - - - } + // Extra configuration for the Forward Tracking + StFwdTrackMaker *fwdTrack = (StFwdTrackMaker*) chain->GetMaker("fwdTrack"); + if ( fwdTrack ){ //if it is in the chain + fwdTrack->SetConfigFile( configFile ); + // write debug histograms and ttree? + fwdTrack->SetGenerateTree( true ); + fwdTrack->SetGenerateHistograms( true ); + // write out wavefront OBJ files + fwdTrack->SetVisualize( false ); } - // The PicoDst - gSystem->Load("libStPicoEvent"); - gSystem->Load("libStPicoDstMaker"); - StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); - cout << "picoMk = " << picoMk << endl; - picoMk->setVtxMode(StPicoDstMaker::Default); - - // Generate FWD QA - StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); - fwdQAMk->SetDebug(2); - chain->AddAfter("fwdTrack", fwdQAMk); - - - - chain->Print(); // Initialize the chain chain->Init(); - // - //_____________________________________________________________________________ // // MAIN EVENT LOOP //_____________________________________________________________________________ for (int i = 0; i < n; i++) { chain->Clear(); - if ( fwdMakerGen ) - fwdMakerGen->SetDebug(1); if (kStOK != chain->Make()) break; } diff --git a/StRoot/StFwdTrackMaker/macro/daq/submit.xml b/StRoot/StFwdTrackMaker/macro/daq/submit.xml index 80111088e96..92676f3ff27 100644 --- a/StRoot/StFwdTrackMaker/macro/daq/submit.xml +++ b/StRoot/StFwdTrackMaker/macro/daq/submit.xml @@ -17,6 +17,11 @@ setup 64b starver dev + module use /cvmfs/star.sdcc.bnl.gov/star-spack/spack/share/spack/modules/linux-rhel7-x86_64/ + module load star-env-root-5.34.38 + module load kitrack-root-5.34.38 + module load genfit-root-5.34.38 + module load rave-2020-08-11 root4star -b -q -l 'daq/daq_track.C( 2, "'$INPUTFILE0'" )' diff --git a/StRoot/StFwdTrackMaker/macro/event/ana.C b/StRoot/StFwdTrackMaker/macro/event/ana.C deleted file mode 100755 index 2a5861eb524..00000000000 --- a/StRoot/StFwdTrackMaker/macro/event/ana.C +++ /dev/null @@ -1,42 +0,0 @@ -//usr/bin/env root4star -l -b -q $0; exit $? -// that is a valid shebang to run script as executable - -void ana( int n = 5000, - const char *inFile = "sim.event.root", - const char *geom = "dev2022") { - TString _chain; - gSystem->Load( "libStarRoot.so" ); - - // Simplest chain with fst, fcs, ftt and fwdTracker - _chain = Form("in, %s, fcsdb, MakeEvent, CMuDst", geom); - - // needed in this wonky spack environment - gROOT->SetMacroPath(".:/star-sw/StRoot/macros:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - - gROOT->LoadMacro("bfc.C"); - bfc(-1, _chain, inFile); - - gSystem->Load("StFcsDbMaker.so"); - StFcsDbMaker* fcsdbmkr = (StFcsDbMaker*) chain->GetMaker("fcsDbMkr"); - cout << "fcsdbmkr="<GetDataSet("fcsDb"); - cout << "fcsdb="<Load("StFwdUtils.so"); - StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); - fwdAna->SetDebug(1); - - // Initialize the chain - chain->Init(); - - //_____________________________________________________________________________ - // - // MAIN EVENT LOOP - //_____________________________________________________________________________ - for (int i = 0; i < n; i++) { - chain->Clear(); - if (kStOK != chain->Make()) - break; - } -} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C b/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C deleted file mode 100644 index 4e616a26997..00000000000 --- a/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C +++ /dev/null @@ -1,137 +0,0 @@ -//usr/bin/env root4star -l root -l -q $0; exit $? -// that is a valid shebang to run script as executable, but with only one arg - -void loadLibs(); -void fwdqa( const Char_t * fileList = "mudst.lis", int nEvents = 5000, int nFiles = 1 ){ - cout << "FileList: " << fileList << endl; - cout << "nFiles: " << nFiles << endl; - cout << "nEvents: " << nEvents << endl; - - // First load some shared libraries we need - loadLibs(); - - // create the chain - StChain *chain = new StChain("StChain"); - - // create the StMuDstMaker - StMuDstMaker *muDstMaker = new StMuDstMaker( 0, - 0, - "", - fileList, - "MuDst.root", - nFiles - ); - - // Initialize the database - // cout << endl << "============ Data Base =========" << endl; - // St_db_Maker *dbMk = new St_db_Maker("db","MySQL:StarDb","$STAR/StarDb","StarDb"); - - - // gSystem->Load("StFwdUtils.so"); - // StFwdAnalysisMaker * fwdAna = new StFwdAnalysisMaker(); - // fwdAna->setMuDstInput(); - // chain->AddMaker(fwdAna); - - // StFcsDbMaker * fcsDb = new StFcsDbMaker(); - // chain->AddMaker(fcsDb); - // fcsDb->SetDebug(); - - gSystem->Load("libStarGeneratorUtil.so"); - gSystem->Load("libgenfit2"); - gSystem->Load("libKiTrack"); - gSystem->Load( "StFwdTrackMaker.so" ); - gSystem->Load("libStEpdUtil.so"); - StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); - fwdQAMk->SetDebug(2); - - // Initialize chain - Int_t iInit = chain->Init(); - - cout << "CHAIN INIT DONE?" << endl; - // ensure that the chain initializes - if ( iInit ) - chain->Fatal(iInit,"on init"); - - // print the chain status - // chain->PrintInfo(); - - //_____________________________________________________________________________ - // - // MAIN EVENT LOOP - //_____________________________________________________________________________ - for (int i = 0; i < nEvents; i++) { - chain->Clear(); - if (kStOK != chain->Make()) - break; - } - - // Chain Finish - if (nEvents > 1) { - cout << "FINISH up" << endl; - chain->Finish(); - } - - delete chain; - - - -} - - - -void loadLibs(){ - // if (gClassTable->GetID("TTable") < 0) { - // gSystem->Load("libStar"); - // gSystem->Load("libPhysics"); - // } - cout << "LL0" << endl; - gSystem->Load("libStarClassLibrary.so"); - gSystem->Load("libStarRoot.so"); - cout << "LL1" << endl; - gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); - loadSharedLibraries(); - cout << "LL2" << endl; - - gSystem->Load("StarMagField"); - gSystem->Load("StMagF"); - gSystem->Load("StDetectorDbMaker"); - gSystem->Load("StTpcDb"); - gSystem->Load("StDaqLib"); - gSystem->Load("StDbBroker"); - gSystem->Load("StDbUtilities"); - gSystem->Load("St_db_Maker"); - - gSystem->Load("StEvent"); - gSystem->Load("StEventMaker"); - gSystem->Load("StarMagField"); - - gSystem->Load("libGeom"); - gSystem->Load("St_g2t"); - - // Added for Run16 And beyond - gSystem->Load("libGeom.so"); - - gSystem->Load("St_base.so"); - gSystem->Load("StUtilities.so"); - gSystem->Load("libPhysics.so"); - gSystem->Load("StarAgmlUtil.so"); - gSystem->Load("StarAgmlLib.so"); - gSystem->Load("libStarGeometry.so"); - gSystem->Load("libGeometry.so"); - - gSystem->Load("xgeometry"); - - gSystem->Load("St_geant_Maker"); - - - // needed since I use the StMuTrack - gSystem->Load("StarClassLibrary"); - gSystem->Load("StStrangeMuDstMaker"); - gSystem->Load("StMuDSTMaker"); - gSystem->Load("StBTofCalibMaker"); - gSystem->Load("StVpdCalibMaker"); - gSystem->Load("StBTofMatchMaker"); - gSystem->Load("StFcsDbMaker"); - - -} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/mudst.C b/StRoot/StFwdTrackMaker/macro/mudst/mudst.C deleted file mode 100755 index 996397d87a6..00000000000 --- a/StRoot/StFwdTrackMaker/macro/mudst/mudst.C +++ /dev/null @@ -1,130 +0,0 @@ -//usr/bin/env root4star -l root -l -q $0; exit $? -// that is a valid shebang to run script as executable, but with only one arg - -void loadLibs(); -void mudst( const Char_t * fileList = "mudst.lis", int nEvents = 5000, int nFiles = 1 ){ - cout << "FileList: " << fileList << endl; - cout << "nFiles: " << nFiles << endl; - cout << "nEvents: " << nEvents << endl; - - // First load some shared libraries we need - loadLibs(); - - // create the chain - StChain *chain = new StChain("StChain"); - - // create the StMuDstMaker - StMuDstMaker *muDstMaker = new StMuDstMaker( 0, - 0, - "", - fileList, - "MuDst.root", - nFiles - ); - - // Initialize the database - // cout << endl << "============ Data Base =========" << endl; - // St_db_Maker *dbMk = new St_db_Maker("db","MySQL:StarDb","$STAR/StarDb","StarDb"); - - - gSystem->Load("StFwdUtils.so"); - StFwdAnalysisMaker * fwdAna = new StFwdAnalysisMaker(); - fwdAna->setMuDstInput(); - chain->AddMaker(fwdAna); - - StFcsDbMaker * fcsDb = new StFcsDbMaker(); - chain->AddMaker(fcsDb); - fcsDb->SetDebug(); - - - // Initialize chain - Int_t iInit = chain->Init(); - - cout << "CHAIN INIT DONE?" << endl; - // ensure that the chain initializes - if ( iInit ) - chain->Fatal(iInit,"on init"); - - // print the chain status - // chain->PrintInfo(); - - //_____________________________________________________________________________ - // - // MAIN EVENT LOOP - //_____________________________________________________________________________ - for (int i = 0; i < nEvents; i++) { - chain->Clear(); - if (kStOK != chain->Make()) - break; - } - - // Chain Finish - if (nEvents > 1) { - cout << "FINISH up" << endl; - chain->Finish(); - } - - delete chain; - - - -} - - - -void loadLibs(){ - // if (gClassTable->GetID("TTable") < 0) { - // gSystem->Load("libStar"); - // gSystem->Load("libPhysics"); - // } - cout << "LL0" << endl; - gSystem->Load("libStarClassLibrary.so"); - gSystem->Load("libStarRoot.so"); - cout << "LL1" << endl; - gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); - loadSharedLibraries(); - cout << "LL2" << endl; - - gSystem->Load("StarMagField"); - gSystem->Load("StMagF"); - gSystem->Load("StDetectorDbMaker"); - gSystem->Load("StTpcDb"); - gSystem->Load("StDaqLib"); - gSystem->Load("StDbBroker"); - gSystem->Load("StDbUtilities"); - gSystem->Load("St_db_Maker"); - - gSystem->Load("StEvent"); - gSystem->Load("StEventMaker"); - gSystem->Load("StarMagField"); - - gSystem->Load("libGeom"); - gSystem->Load("St_g2t"); - - // Added for Run16 And beyond - gSystem->Load("libGeom.so"); - - gSystem->Load("St_base.so"); - gSystem->Load("StUtilities.so"); - gSystem->Load("libPhysics.so"); - gSystem->Load("StarAgmlUtil.so"); - gSystem->Load("StarAgmlLib.so"); - gSystem->Load("libStarGeometry.so"); - gSystem->Load("libGeometry.so"); - - gSystem->Load("xgeometry"); - - gSystem->Load("St_geant_Maker"); - - - // needed since I use the StMuTrack - gSystem->Load("StarClassLibrary"); - gSystem->Load("StStrangeMuDstMaker"); - gSystem->Load("StMuDSTMaker"); - gSystem->Load("StBTofCalibMaker"); - gSystem->Load("StVpdCalibMaker"); - gSystem->Load("StBTofMatchMaker"); - gSystem->Load("StFcsDbMaker"); - - -} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/pico.C b/StRoot/StFwdTrackMaker/macro/mudst/pico.C deleted file mode 100755 index 7ff3f3a63ee..00000000000 --- a/StRoot/StFwdTrackMaker/macro/mudst/pico.C +++ /dev/null @@ -1,602 +0,0 @@ -//usr/bin/env root4star -l -b -q $0; exit $? -///////////////////////////////////////////////////////////////////////////// -// $Id: genDst.C,v 1.9 2020/10/10 07:16:56 genevb Exp $ -// Author: G. Van Buren (BNL) -// -// Description: -// Process a MuDst for... -// ...creating a PicoDst -// ...re-running vertex-finding to re-create MuDsts -// -// Options are space-separated or comma-separated, -// and case-insensitive. They can be attributed -// whose values are provided after a ':'. -// -// Example options for creating PicoDsts: -// picoDst -// btofMatch -// btofStartless -// mtdMatch -// y2017a -// -// Example lists of options: -// "picoDst" -// "DbV20200125,picoDst,mtdMatch,y2014a" -// -// Example options for vertex-finding: -// beamline, beamline1D, beamline3D (otherwise no beamline) -// useBTOFmatchOnly -// VFstore:100 -// -// Example lists of options: -// "VFPPVnoCTB,beamline1D,VFstore:100" -// "VFPPVnoCTB,beamline3D" -// -///////////////////////////////////////////////////////////////////////////// - -void afterburner(); - -void genDst(unsigned int Last, - const char* options, - char* infile, - char* outfile=0); - -void genDst(unsigned int First, - unsigned int Last, - const char* options, - char* infile, - char* outfile=0); - -void loadLibs() -{ - gROOT->Macro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); - gSystem->Load("StDbBroker"); - gSystem->Load("St_db_Maker"); - gSystem->Load("StEEmcUtil"); -} - -void loadLibsVF() -{ - gSystem->Load("libMinuit"); - gSystem->Load("Sti"); - gSystem->Load("StBTofUtil"); - gSystem->Load("StGenericVertexMaker"); -} - -void loadLibsPico() -{ - - // EMCs and FMS need DB+converters - gSystem->Load("StEmcRawMaker"); - gSystem->Load("StEmcADCtoEMaker"); - gSystem->Load("StPreEclMaker"); - gSystem->Load("StEpcMaker"); - gSystem->Load("StEEmcDbMaker"); - gSystem->Load("StFmsUtil"); - gSystem->Load("StFmsDbMaker"); - gSystem->Load("StTriggerUtilities"); - - // The PicoDst - gSystem->Load("libStPicoEvent"); - gSystem->Load("libStPicoDstMaker"); -} - -void loadLibsAgML() -{ - // load support libraries. util will fail to load for agml 1.0, but you can ignore the error - gSystem->Load("libStarAgmlUtil"); - gSystem->Load("libStarAgmlLib"); - - // load geometry modules and master steering codes... - gSystem->Load("libGeometry"); - gSystem->Load("libStarGeometry"); -} - -void loadLibsMtd() -{ - gSystem->Load("StDetectorDbMaker"); - gSystem->Load("StarMagField"); - gSystem->Load("StMagF"); - gSystem->Load("StMtdUtil"); - gSystem->Load("StMtdMatchMaker"); - gSystem->Load("StMtdCalibMaker"); -} - -void loadLibsBTof() -{ - gSystem->Load("StBTofUtil"); - gSystem->Load("StVpdCalibMaker"); - gSystem->Load("StBTofCalibMaker"); - gSystem->Load("StBTofMatchMaker"); -} - -void loadLibsETof() -{ - gSystem->Load("StETofUtil"); - gSystem->Load("StETofCalibMaker"); - gSystem->Load("StETofHitMaker"); - gSystem->Load("StETofMatchMaker"); -} - -void loadLibsFwd() -{ - gSystem->Load("libStDetectorDbMaker.so"); - gSystem->Load("StEvent"); - gSystem->Load("StEventMaker"); - - // Fwd - gSystem->Load("StFwdUtils"); - gSystem->Load("libStarGeneratorUtil.so"); - gSystem->Load("libXMLIO"); - gSystem->Load("libgenfit2"); - gSystem->Load("libKiTrack"); - // gSystem->Load("StarGeneratorUtil") ; - gSystem->Load("libMathMore"); - gSystem->Load("StEventUtilities"); - gSystem->Load("StEpdUtil"); - gSystem->Load("StFwdTrackMaker"); - gSystem->Load("StFwdUtils"); - //Ftt - gSystem->Load("StFttDbMaker"); - gSystem->Load("StFttRawHitMaker"); - gSystem->Load("StFttHitCalibMaker"); - gSystem->Load("StFttClusterMaker"); - gSystem->Load("StFttPointMaker"); - // Fcs - gSystem->Load("libMinuit.so"); - gSystem->Load("StFcsDbMaker"); - gSystem->Load("StFcsRawHitMaker"); - gSystem->Load("StFcsWaveformFitMaker"); - gSystem->Load("StFcsClusterMaker"); - gSystem->Load("StFcsPointMaker"); - gSystem->Load("StFcsTrackMatchMaker"); - - // Fst - gSystem->Load("StFstUtil"); - gSystem->Load("StFstDbMaker"); - gSystem->Load("StFstRawHitMaker"); - gSystem->Load("StFstClusterMaker"); - gSystem->Load("StFstHitMaker"); -} - -void procGeoTag(TObjArray* optionTokens) -{ - if (TClass::GetClass("AgBlock")) return; // arbitrarily chosen AgML class - loadLibsAgML(); - - const char* tag = 0; - for (int tk=0; tk < optionTokens->GetEntries(); tk++) { - TString& tok = ((TObjString*) (optionTokens->At(tk)))->String(); - if (tok.BeginsWith("y20")){ - tag = tok.Data(); - optionTokens->RemoveAt(tk); - optionTokens->Compress(); - break; - } - } - - // Let agml know we want the ROOT geometry - AgModule::SetStacker( new StarTGeoStacker ); - - // now pass the geometry "tag" and build. If the class StarGeometry exists, we have - // AgML 2.0 and can run using the new steering. Otherwise, old steering codes... - if (tag) { - if ( TClass::GetClass("StarGeometry") ) { StarGeometry::Construct( tag ); } - else { ( new Geometry() )->ConstructGeometry(tag); } - } else { - gMessMgr->Warning() << "No geometry tag passed! (e.g. y2017a)" << endm; - } -} - -bool findAndRemoveOption(const char* optionName, TObjArray* optionTokens) -{ - TString optName = optionName; - optName.ToLower(); - TObject* obj = optionTokens->FindObject(optName.Data()); - if (obj) { - optionTokens->Remove(obj); - optionTokens->Compress(); - return true; - } - return false; -} - -void genDst(unsigned int First, - unsigned int Last, - const char* options, - char* infile, - char* outfile) -{ - loadLibs(); - - StChain fullChain("genDst"); - fullChain.SetDebug(1); - - StMuDstMaker muDstMaker(0, 0, "", infile, "st:MuDst.root", 1e9); // set up maker in read mode - // 0, 0 this means read mode - // dir read all files in this directory - // file bla.lis read all file in this list, if (file!="") dir is ignored - // filter apply filter to filenames, multiple filters are separated by ':' - // 10 maximum number of file to read - - - TChain& muDstChain = *muDstMaker.chain(); - unsigned int nEntries = muDstChain.GetEntries(); - unsigned int LastToRead = Last > 0 ? min(Last, nEntries) : nEntries; - gMessMgr->Info() << nEntries << " events in chain, " << LastToRead-First+1 << " will be read." << endm; - - // St_db_Maker* db = new St_db_Maker("db", "StarDb", "MySQL:StarDb", "$STAR/StarDb"); - - // Initialize some values and pointers - StMaker* processMaker = 0; - TFile* outFile = 0; - TTree* muDstTreeOut = 0; - - // Basic decisions based on options - TString CasedOptions = options; - TString Options = options; - Options.ToLower(); - TString optDelim = " ,"; - TObjArray* optionTokens = Options.Tokenize(optDelim); - optionTokens->SetOwner(kTRUE); - - // Determine database flavors - TString flavors = "ofl"; // default flavor for offline - - // simulation flavors - if (findAndRemoveOption("Simu",optionTokens) && ! findAndRemoveOption("NoSimuDb",optionTokens)) - flavors.Prepend("sim+"); - - // filestream flavors - TObject* firstFile = muDstChain.GetListOfFiles()->At(0); - if (firstFile) { - TString firstFileName = firstFile->GetTitle(); - firstFileName = firstFileName(firstFileName.Last('/')+1,firstFileName.Length()); - if (firstFileName.BeginsWith("st_")) { - TString fileStream = firstFileName(3,firstFileName.Index('_',3)-3); - if (fileStream.Length()>0) flavors.Prepend(fileStream += '+'); - } - } - - // gMessMgr->Info() << "Using DB flavors: " << flavors << endm; - // db->SetFlavor(flavors.Data()); - - if (findAndRemoveOption("picodst",optionTokens)) { - // _________________________________________________________________ - // Processing with generation of PicoDsts - - loadLibsPico(); - - // Specify active branches but first disable all branches - muDstMaker.SetStatus("*", 0); - muDstMaker.SetStatus("MuEvent", 1); - muDstMaker.SetStatus("PrimaryVertices", 1); - muDstMaker.SetStatus("PrimaryTracks", 1); - muDstMaker.SetStatus("GlobalTracks", 1); - muDstMaker.SetStatus("CovGlobTrack", 1); - muDstMaker.SetStatus("BTof*", 1); - muDstMaker.SetStatus("Emc*", 1); - muDstMaker.SetStatus("MTD*", 1); - muDstMaker.SetStatus("ETof*", 1); - muDstMaker.SetStatus("Epd*", 1); - muDstMaker.SetStatus("Fms*", 1); - muDstMaker.SetStatus("MCAll", 1); - muDstMaker.SetStatus("Fwd*", 1); - muDstMaker.SetStatus("Fcs*", 1); - muDstMaker.SetStatus("Ftt*", 1); - muDstMaker.SetStatus("Fst*", 1); - - // EMCs - // StEEmcDbMaker* eemcDb = new StEEmcDbMaker; - // StEmcADCtoEMaker* adc2e = new StEmcADCtoEMaker(); - // adc2e->saveAllStEvent(true); - // StPreEclMaker* pre_ecl = new StPreEclMaker(); - // StEpcMaker* epc = new StEpcMaker(); - - // FMS - // StFmsDbMaker* fmsDb = new StFmsDbMaker("fmsDb"); - - // Trigger simulator - // StTriggerSimuMaker* trigSimu = new StTriggerSimuMaker; - // trigSimu->setMC(false); - // trigSimu->useBemc(); - // trigSimu->useEemc(); - // trigSimu->useOfflineDB(); - // trigSimu->bemc->setConfig(StBemcTriggerSimu::kOffline); - - loadLibsFwd(); - - // If you need the geometry you can load it with this: - // gROOT->LoadMacro("/star-sw/StarVMC/Geometry/macros/loadStarGeometry.C"); - // loadStarGeometry( "y2023" ); - - // This makes the Fcs and Ftt hits show up in StEvent, - // and produces an StEvent for StFwdTracks to go into - StMuDst2StEventMaker * mu2ev = new StMuDst2StEventMaker(); - - // Re-run the FCS chain - StFcsDbMaker * fcsDbMk = new StFcsDbMaker(); - // StFcsWaveformFitMaker * fcsWFF = new StFcsWaveformFitMaker(); - // StFcsClusterMaker * fcsClu = new StFcsClusterMaker(); - // StFcsPointMaker * fcsPoint = new StFcsPointMaker(); - - // FTT chain - StFttDbMaker * fttDbMk = new StFttDbMaker(); - StFttHitCalibMaker * ftthcm = new StFttHitCalibMaker(); - StFttClusterMaker * fttclu = new StFttClusterMaker(); - fttclu->SetTimeCut(1, -40, 40); - StFttPointMaker * fttpoint = new StFttPointMaker(); - - - StFwdTrackMaker * fwdTrack = new StFwdTrackMaker(); - fwdTrack->setConfigForData( ); - fwdTrack->setGeoCache( "fGeom.root" ); - fwdTrack->setSeedFindingWithFst(); - fwdTrack->setIncludePrimaryVertexInFit(true); - fwdTrack->setMaxFailedHitsInFit(2); - fwdTrack->SetDebug(2); - - StFcsTrackMatchMaker *match = new StFcsTrackMatchMaker(); - match->setMaxDistance(6,10); - match->setFileName("fcstrk.root"); - match->SetDebug(); - - StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); - fwdAna->SetDebug(); - fwdAna->setLocalOutputFile( "StFwdAnalysisMaker.root"); - - StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); - fwdFitQA->SetDebug(); - - StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); - fwdQAMk->SetDebug(2); - // chain->AddAfter("fwdTrack", fwdQAMk); - - if (findAndRemoveOption("btofmatch",optionTokens)) { - - procGeoTag(optionTokens); - loadLibsBTof(); - - // instantiate both VPD and BTOF CalibMakers and MatchMaker and point them to the MuDST - StBTofMatchMaker* btofMatch = new StBTofMatchMaker(); - btofMatch->setMuDstIn(); - StVpdCalibMaker *vpdCalib = new StVpdCalibMaker(); - vpdCalib->setMuDstIn(); - StBTofCalibMaker *btofCalib = new StBTofCalibMaker(); - btofCalib->setMuDstIn(); - - if (findAndRemoveOption("btofstartless",optionTokens)) { - //Disable the VPD as start detector, BTOF calib maker will switch to the "start-less" algorithm. - vpdCalib->setUseVpdStart(kFALSE); - } - - } - - if (findAndRemoveOption("etofmatch",optionTokens)) { - - procGeoTag(optionTokens); - loadLibsETof(); - - // instantiate eTOF CalibMakers, HitMaker and MatchMaker - StETofCalibMaker* etofCalib = new StETofCalibMaker(); - StETofHitMaker* etofHit = new StETofHitMaker(); - StETofMatchMaker* etofMatch = new StETofMatchMaker(); - - } - - if (findAndRemoveOption("mtdmatch",optionTokens)) { - - procGeoTag(optionTokens); - loadLibsMtd(); - - StMagFMaker* magfMk = new StMagFMaker; - StMtdMatchMaker* mtdMatchMaker = new StMtdMatchMaker(); - StMtdCalibMaker* mtdCalibMaker = new StMtdCalibMaker("mtdcalib"); - - } - - processMaker = (StMaker*) (new StPicoDstMaker(StPicoDstMaker::IoWrite, infile, "picoDst")); - StPicoDstMaker *picoMk = (StPicoDstMaker*) (processMaker); - picoMk->setVtxMode(StPicoDstMaker::Vpd); - gMessMgr->Info() << "PicoSetup Complete" << endm; - } else if (Options.Contains("fwd")) { - // _________________________________________________________________ - // Processing with new vertex-finding - - // loadLibsVF(); - - // Specify inactive branches but first enable all branches - muDstMaker.SetStatus("*",1); - muDstMaker.SetStatus("PrimaryTracks",0); - muDstMaker.SetStatus("PrimaryVertices",0); - - // Create new branch - // TClonesArray* verticesRefitted = new TClonesArray("StMuPrimaryVertex", 1000); - - // Specify output - if (outfile) { - outFile = new TFile(outfile, "RECREATE"); - } else { - // Use the same filename for output as was given by input - TString fileStr = infile; - Ssiz_t dir = fileStr.Last('/'); - if (dir<0) { - gMessMgr->Error() << "No specification for output when input is in local directory!" << endm; - return; - } - fileStr.Remove(0,dir+1); - outFile = new TFile(fileStr.Data(), "RECREATE"); - } - muDstTreeOut = muDstChain.CloneTree(0); - muDstTreeOut->Branch("PrimaryVertices", &verticesRefitted, 65536, 99); - - // processMaker = (StMaker*) (new StGenericVertexMaker()); - // processMaker->ToWhiteConst("vtxArray",verticesRefitted); - // processMaker->SetAttr("useMuDst",1); - - } else { - - gMessMgr->Info() << "No processing specified - just reading a MuDst?" << endm; - // User code may be inserted here - - } - - // Set additional options (except DbV) as maker attributes - if (processMaker) { - for (int tk=0; tk < optionTokens->GetEntries(); tk++) { - TString& Tag = ((TObjString*) (optionTokens->At(tk)))->String(); - - // copy of DbV code from StBFChain.cxx - if (Tag.BeginsWith("dbv")) { - int FDate=0,FTime=0; - if (Tag.Length() == 11) (void) sscanf(Tag.Data(),"dbv%8d",&FDate); - if (Tag.Length() == 18) (void) sscanf(Tag.Data(),"dbv%8d.%6d",&FDate,&FTime); - if (FDate) { - // db->SetMaxEntryTime(FDate,FTime); - // gMessMgr->Info() << "\tSet DataBase max entry time " << FDate << "/" << FTime - // << " for St_db_Maker(\"" << db->GetName() <<"\")" << endm; - } - continue; - } - - // assign attributes - StMaker* attrMaker = processMaker; - Ssiz_t delim = Tag.First(':'); - // look for "::" to set attributes for a different maker - if (delim > 0 && Tag[delim+1] == ':') { - TString altMakerName = Tag(0,delim); - // GetMaker...() functions are case sensitive, so find original case - Ssiz_t casedMakerNameIdx = CasedOptions.Index(altMakerName,0,TString::ECaseCompare::kIgnoreCase); - if (casedMakerNameIdx >= 0) altMakerName = CasedOptions(casedMakerNameIdx,delim); - StMaker* altMaker = fullChain.GetMaker(altMakerName.Data()); - if (!altMaker) altMaker = fullChain.GetMakerInheritsFrom(altMakerName.Data()); - if (!altMaker) { - gMessMgr->Warning() << "No maker found with name or class " << altMakerName.Data() << endm; - continue; - } - attrMaker = altMaker; - Tag.Remove(0,delim+2); - delim = Tag.First(':'); - } - if (delim < 0) { - attrMaker->SetAttr(Tag.Data(),1); - } else { - TString key(Tag(0,delim)); - TString& val = Tag.Remove(0,delim+1); - if (val.IsDigit()) { attrMaker->SetAttr(key.Data(),val.Atoi()); } - else if (val.IsFloat()) { attrMaker->SetAttr(key.Data(),val.Atof()); } - else { attrMaker->SetAttr(key.Data(),val.Data()); } - } - } - processMaker->PrintAttr(); - } - - { - TDatime t; - gMessMgr->QAInfo() << Form("Run is started at Date/Time %i/%i",t.GetDate(),t.GetTime()) << endm; - } - gMessMgr->QAInfo() << Form("Run on %s in %s",gSystem->HostName(),gSystem->WorkingDirectory()) << endm; - gMessMgr->QAInfo() << Form("with %s", fullChain.GetCVS()) << endm; - - gMessMgr->Info() << "Chain setup Complete" << endm; - - // Main loop over events - int iInit = fullChain.Init(); - if (iInit >= kStEOF) {fullChain.FatalErr(iInit,"on init"); return;} - if (Last == 0) return; - int eventCount = 0; - // Skip, if any - if (First > 1) fullChain.Skip(First - 1); - for (unsigned int iEvent = First; iEvent <= LastToRead; iEvent++) - { - // make an StEvent so that Fwd can save tracks, etc. - // StEvent * stEv = new StEvent(); - // fullChain.AddData( stEv ); - fullChain.SetDebug(2); - fwdTrack->SetDebug(2); - - int iMake = fullChain.Make(); - if (iMake) {fullChain.FatalErr(iMake,"on make"); return;} - - if (muDstTreeOut) muDstTreeOut->Fill(); - - int iClear = fullChain.Clear(); - if (iClear) {fullChain.FatalErr(iClear,"on clear"); return;} - eventCount++; - } - fullChain.Finish(); - - // - // ATTENTION - please DO NOT change the format of the next 2 lines, - // they are used by our DataManagement parsers to detect a generation - // was succesful and thereafter Catalog the produced files. - // Thank you. - // - gMessMgr->QAInfo() << "NumberOfEvents= " << eventCount << endm; - gMessMgr->QAInfo() << "Run completed " << endm; - - if (outFile) { - outFile->Write(); - outFile->Close(); - delete outFile; - } - - // delete db; - delete processMaker; - delete optionTokens; -} - -//__________________________________________________________ -void genDst(unsigned int Last, - const char* options, - char* infile, - char* outfile) -{ - cout << TString::Format("genDst( %u, '%s', '%s', '%s' )", Last, options, infile, outfile ) << endl; - genDst(1,Last,options,infile,outfile); -} - -void pico(){ - genDst(5000, "y2023a picodst PicoVtxMode:PicoVtxDefault", "/work/st_fwd_22355048_raw_1000012.MuDst.root", "PROD.root"); -} - -void pico( TString f, int n = 500){ - genDst(n, "y2023a picodst PicoVtxMode:PicoVtxDefault", f.Data(), "PROD.root" /*Not used?*/); -} - -///////////////////////////////////////////////////////////////////////////// -// -// $Log: genDst.C,v $ -// Revision 1.10 2022/05/12 07:16:56 weidenkaff -// Added eTOF support -// -// $Log: genDst.C,v $ -// Revision 1.9 2020/10/10 07:16:56 genevb -// Specify makers to set attributes -// -// Revision 1.8 2020/08/19 15:27:33 genevb -// Add DB flavors -// -// Revision 1.7 2020/01/25 05:10:00 genevb -// Include DbV, more like BFC -// -// Revision 1.6 2019/09/18 17:54:48 genevb -// Acivate additional branches by default -// -// Revision 1.5 2019/03/21 18:53:34 jeromel -// Added ATTENTION message -// -// Revision 1.4 2019/01/15 17:24:29 genevb -// Added FMS -// -// Revision 1.3 2018/03/16 18:41:14 genevb -// Add BTof-matching -// -// Revision 1.2 2017/12/15 18:36:53 genevb -// Remove explicit function of StPicoDstMaker...params should be passed by attribute -// -// Revision 1.1 2017/12/05 16:47:58 genevb -// Introduce genDst.C for creating new Dsts from MuDsts -// -// -///////////////////////////////////////////////////////////////////////////// diff --git a/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml b/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml deleted file mode 100644 index d6279fd1c97..00000000000 --- a/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - echo "JOBINDEX = ${JOBINDEX}" - echo "JOBID = ${JOBID}" - - ln -s StRoot/StFwdTrackMaker/macro/mudst/ mudst - ls -lah - - starver dev - root4star -b -q -l 'mudst/pico.C( "'$INPUTFILE0'", 50000 )' - - mv StFwdAnalysisMaker.root ${JOBID}_StFwdAnalysisMaker.root - mv StFwdFitQAMaker.root ${JOBID}_StFwdFitQAMaker.root - - - - - file:./StRoot - file:./fGeom.root - file:.sl73_gcc485/ - - - - - /gpfs01/star/pwg_tasks/FwdCalib/PROD/gen - - diff --git a/StRoot/StFwdTrackMaker/macro/qa/mudst.C b/StRoot/StFwdTrackMaker/macro/qa/mudst.C deleted file mode 100755 index 966097b055b..00000000000 --- a/StRoot/StFwdTrackMaker/macro/qa/mudst.C +++ /dev/null @@ -1,78 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'("'$1'")'; exit $? - -#include "TTree.h" -#include "TClonesArray.h" - -void mudst( TString df = "sim.MuDst.root" ){ - - // setup and make sure libraries are loaded - gSystem->Load( "libStarRoot.so" ); - gSystem->Load("libStarClassLibrary.so"); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); - loadSharedLibraries(); - - gSystem->Load("libgenfit2.so"); - gSystem->Load("libKiTrack.so"); - gSystem->Load( "libStFwdTrackMaker.so" ); - - // now open our data file - TFile *f = new TFile(df); - TTree *t = (TTree*)f->Get("MuDst"); - - // create the readers for each branch - // TClonesArray *mcTracks = new TClonesArray("StMuMcTrack"); - // t->GetBranch("mcTracks")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("mcTracks",&mcTracks); - - // TClonesArray *fttPoints = new TClonesArray("StMuFttPoint"); - // t->GetBranch("fttPoints")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("fttPoints",&fttPoints); - - // TClonesArray *fttClusters = new TClonesArray("StMuFttCluster"); - // t->GetBranch("fttClusters")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("fttClusters",&fttClusters); - - // TClonesArray *fstPoints = new TClonesArray("StMuFstHit"); - // t->GetBranch("fstHits")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("fstHits",&fstPoints); - - // TClonesArray *wcal = new TClonesArray("FcsClusterWithStarXYZ"); - // t->GetBranch("wcalClusters")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("wcalClusters",&wcal); - - // TClonesArray *wcalHits = new TClonesArray("FcsHitWithStarXYZ"); - // t->GetBranch("wcalHits")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("wcalHits",&wcalHits); - - // TClonesArray *hcal = new TClonesArray("FcsClusterWithStarXYZ"); - // t->GetBranch("hcalClusters")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("hcalClusters",&hcal); - - // TClonesArray *hcalHits = new TClonesArray("FcsHitWithStarXYZ"); - // t->GetBranch("hcalHits")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("hcalHits",&hcalHits); - - // TClonesArray *epdHits = new TClonesArray("FcsHitWithStarXYZ"); - // t->GetBranch("epdHits")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("epdHits",&epdHits); - - TClonesArray *fwdTracks = new TClonesArray("StMuFwdTrack"); - t->GetBranch("FwdTrack")->SetAutoDelete(kFALSE); - t->SetBranchAddress("FwdTrack",&fwdTracks); - - // TClonesArray *seeds = new TClonesArray("StMuFwdTrackSeedPoint"); - // t->GetBranch("seeds")->SetAutoDelete(kFALSE); - // t->SetBranchAddress("seeds",&seeds); - - - //loop over the events - for ( int i = 0; i < t->GetEntries(); i++ ){ - t->GetEntry(i); - for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ - StMuFwdTrack *track = fwdTracks->At(j); - printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); - } - } - cout << "Processed: " << t->GetEntries() << " entries" << endl; -} \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/qa/qa.C b/StRoot/StFwdTrackMaker/macro/qa/qa.C deleted file mode 100755 index 926d9e1d472..00000000000 --- a/StRoot/StFwdTrackMaker/macro/qa/qa.C +++ /dev/null @@ -1,281 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'("'"$1"'")'; exit $? - -#include "TTree.h" -#include "TClonesArray.h" -#include -// #include <__config> - -// TClonesArrays to read from the tree -TClonesArray *mcTracks = NULL; -TClonesArray *fttPoints = NULL; -TClonesArray *fttClusters = NULL; -TClonesArray *fstPoints = NULL; -TClonesArray *wcal = NULL; -TClonesArray *wcalHits = NULL; -TClonesArray *hcal = NULL; -TClonesArray *hcalHits = NULL; -TClonesArray *epdHits = NULL; -TClonesArray *fwdTracks = NULL; -TClonesArray *seeds = NULL; -TTree *t = NULL; - -std::map histograms; -TH1* addH1( string name, string title, int nx, float x1, float x2 ){ - histograms[name] = new TH1F( name.c_str(), title.c_str(), nx, x1, x2 ); - return histograms[name]; -} -TH2* addH2( string name, string title, int nx, float x1, float x2, int ny, float y1, float y2 ){ - histograms[name] = new TH2F( name.c_str(), title.c_str(), nx, x1, x2, ny, y1, y2 ); - return (TH2*)histograms[name]; -} -inline TH1 *getH1( string name ){ - // printf( "Looking for histogram name=[%s]", name.c_str() ); - assert( histograms.count( name ) && "Histogram cannot be found" && name.c_str() ); - assert( histograms[name] && TString::Format( "Histogram %s is NULL", name.c_str() ) ); - return histograms[name]; -} -inline TH2 *getH2( string name ){ - return (TH2*) getH1( name ); -} - -void setupRead( TString filename = "fwdtree.root" ){ - // setup and make sure libraries are loaded - gSystem->Load( "libStarRoot.so" ); - gSystem->Load("libStarClassLibrary.so"); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); - loadSharedLibraries(); - - gSystem->Load("libgenfit2.so"); - gSystem->Load("libKiTrack.so"); - gSystem->Load( "libStFwdTrackMaker.so" ); - - // now open our data file - TFile *f = new TFile(filename); - t = (TTree*)f->Get("fwd"); - - // create the readers for each branch - mcTracks = new TClonesArray("StMuMcTrack"); - t->GetBranch("mcTracks")->SetAutoDelete(kFALSE); - t->SetBranchAddress("mcTracks",&mcTracks); - - fttPoints = new TClonesArray("StMuFttPoint"); - t->GetBranch("fttPoints")->SetAutoDelete(kFALSE); - t->SetBranchAddress("fttPoints",&fttPoints); - - fttClusters = new TClonesArray("StMuFttCluster"); - t->GetBranch("fttClusters")->SetAutoDelete(kFALSE); - t->SetBranchAddress("fttClusters",&fttClusters); - - fstPoints = new TClonesArray("StMuFstHit"); - t->GetBranch("fstHits")->SetAutoDelete(kFALSE); - t->SetBranchAddress("fstHits",&fstPoints); - - wcal = new TClonesArray("FcsClusterWithStarXYZ"); - t->GetBranch("wcalClusters")->SetAutoDelete(kFALSE); - t->SetBranchAddress("wcalClusters",&wcal); - - wcalHits = new TClonesArray("FcsHitWithStarXYZ"); - t->GetBranch("wcalHits")->SetAutoDelete(kFALSE); - t->SetBranchAddress("wcalHits",&wcalHits); - - hcal = new TClonesArray("FcsClusterWithStarXYZ"); - t->GetBranch("hcalClusters")->SetAutoDelete(kFALSE); - t->SetBranchAddress("hcalClusters",&hcal); - - hcalHits = new TClonesArray("FcsHitWithStarXYZ"); - t->GetBranch("hcalHits")->SetAutoDelete(kFALSE); - t->SetBranchAddress("hcalHits",&hcalHits); - - epdHits = new TClonesArray("FcsHitWithStarXYZ"); - t->GetBranch("epdHits")->SetAutoDelete(kFALSE); - t->SetBranchAddress("epdHits",&epdHits); - - fwdTracks = new TClonesArray("StMuFwdTrack"); - t->GetBranch("reco")->SetAutoDelete(kFALSE); - t->SetBranchAddress("reco",&fwdTracks); - - seeds = new TClonesArray("StMuFwdTrackSeedPoint"); - t->GetBranch("seeds")->SetAutoDelete(kFALSE); - t->SetBranchAddress("seeds",&seeds); -} - -void qaMomentumResolution(){ - - if ( histograms.count( "curveRcVsMc" ) == 0 ) { - printf( "Creating Momentum Resolution Histograms\n" ); - addH2( "curveRcVsMc", "Track curvature; MC; RC", 200, -10, 10, 200, -10, 10 ); - addH2( "curveMcVsPtMc", ";MC Pt; MC Curve ", 200, 0, 10, 100, 0, 10 ); - addH2( "ptRcVsMc", "Track Pt; MC; RC", 200, 0, 10, 200, 0, 10 ); - addH1( "curveRes", "Curvature Resolution; (C^{MC}-C^{RC})/C^{MC}", 200, -2, 2 ); - addH1( "transMomRes", "Pt Resolution; (Pt^{MC} - Pt^{RC}) / Pt^{MC}", 200, -2, 2 ); - addH1( "deltaCharge", "deltaCharge; |q_{MC}-q_{RC}|;counts;", 5, 0, 5 ); - } - - const TH2 * hCurveRcVsMc = getH2( "curveRcVsMc" ); - const TH2 * hCurveMcVsPtMc = getH2( "curveMcVsPtMc" ); - const TH2 * hPtRcVsMc = getH2( "ptRcVsMc" ); - - const TH1 * hCurveRes = getH1( "curveRes" ); - const TH1 * hTransMomRes = getH1( "transMomRes" ); - const TH1 * hDeltaCharge = getH1( "deltaCharge" ); - - for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ - - StMuFwdTrack *fwt = fwdTracks->At(j); - UShort_t indexToMatchedMC = fwt->idTruth() - 1; - // // cout << "Processing track " << j << ", mcid = " << indexToMatchedMC << endl; - if (indexToMatchedMC >= mcTracks->GetEntries()) continue; - // // get corresponding MC track - StMuMcTrack *mct = mcTracks->At(indexToMatchedMC); - - float curveMc = fabs(mct->Charge() / mct->pT()); - float curveRc = fabs(fwt->charge() / fwt->momentum().Pt()); - // // cout << "mct->pT() = " << mct->pT() << endl; - if ( mct->pT() > 0.1 && fwt->pval() > 0.01){ - hDeltaCharge->Fill( abs( mct->Charge() - fwt->charge() ) ); - hCurveRes->Fill( (curveMc - curveRc) / curveMc ); - hTransMomRes->Fill( (mct->pT() - fwt->momentum().Pt()) / mct->pT() ); - - hCurveRcVsMc->Fill( curveMc, curveRc ); - hCurveMcVsPtMc->Fill( curveMc, mct->pT() ); - hPtRcVsMc->Fill( mct->pT(), fwt->momentum().Pt() ); - } - } -} - -void qaFCSTrackMatch(){ - - if (histograms.count("dxWCAL") == 0){ - addH1( "dxWCAL", "WCAL; dx", 500, -100, 100 ); - addH1( "dxWCAL2", "WCAL; dx", 500, -100, 100 ); - addH1( "dyWCAL", "WCAL; dy", 500, -100, 100 ); - addH1( "dxHCAL", "HCAL; dx", 500, -100, 100 ); - addH1( "drWCAL", "WCAL; dr", 500, 0, 100 ); - addH1( "drHCAL", "HCAL; dr", 500, 0, 100 ); - addH2( "wcalTrackX", "; WCAL x; Track x", 500, -50, 50, 500, -50, 50 ); - addH2( "wcalTrackY", "; WCAL y; Track y", 500, -50, 50, 500, -50, 50 ); - } - - const TH1 * hdxWCAL = getH1("dxWCAL"); - const TH1 * hdxWCAL2 = getH1("dxWCAL2"); - const TH1 * hdyWCAL = getH1("dyWCAL"); - const TH1 * hdxHCAL = getH1("dxHCAL"); - - const TH1 * hdrWCAL = getH1("drWCAL"); - const TH1 * hdrHCAL = getH1("drHCAL"); - - const TH2 * hWCALX = getH1("wcalTrackX"); - const TH2 * hWCALY = getH1("wcalTrackY"); - - for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ - StMuFwdTrack *track = (StMuFwdTrack *)fwdTracks->At(j); - - // printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); - if ( track->pval() < 0.01 ) continue; - StMuFwdTrackProjection projWCAL; - track->getProjectionFor(kFcsWcalId, projWCAL); - // printf("Projection @ WCAL: det=%d, x=%f, y=%f, z=%f\n", projWCAL.mDetId, projWCAL.mXYZ.X(), projWCAL.mXYZ.Y(), projWCAL.mXYZ.Z()); - - StMuFwdTrackProjection projHCAL; - track->getProjectionFor(kFcsHcalId, projHCAL); - // printf("Projection @ HCAL: det=%d, x=%f, y=%f, z=%f\n", projHCAL.mDetId, projHCAL.mXYZ.X(), projHCAL.mXYZ.Y(), projHCAL.mXYZ.Z()); - - // loop over WCAL clusters - for ( int k = 0; k < wcal->GetEntries(); k++ ){ - FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); - double dx = projWCAL.mXYZ.X() - cluster->mXYZ.X(); - double dy = projWCAL.mXYZ.Y() - cluster->mXYZ.Y(); - double dr = sqrt( dx*dx + dy*dy ); - - hdxWCAL2->Fill( dx ); - if ( projWCAL.mXYZ.X() < 0 && cluster->mClu->detectorId() == 1 ) continue; - if ( projWCAL.mXYZ.X() > 0 && cluster->mClu->detectorId() == 0 ) continue; - - hdxWCAL->Fill( dx ); - hdyWCAL->Fill( dy ); - // printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); - hdrWCAL->Fill( dr ); - - hWCALX->Fill( cluster->mXYZ.X(), projWCAL.mXYZ.X() ); - hWCALY->Fill( cluster->mXYZ.Y(), projWCAL.mXYZ.Y() ); - } - - // loop over WCAL clusters - for ( int k = 0; k < hcal->GetEntries(); k++ ){ - FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)hcal->At(k); - double dx = projHCAL.mXYZ.X() - cluster->mXYZ.X(); - double dy = projHCAL.mXYZ.Y() - cluster->mXYZ.Y(); - double dr = sqrt( dx*dx + dy*dy ); - - hdxHCAL->Fill( dx ); - hdrHCAL->Fill( dr ); - } - - } -} - - -// Loop on events -void eventLoop( int numEventsLimit = -1, int reportEveryNthEvent = -1 ){ - int lastEventIndex = (numEventsLimit > 0 ? numEventsLimit : t->GetEntries() ); - for ( int i = 0; i < lastEventIndex; i++ ){ - t->GetEntry(i); - if ( reportEveryNthEvent > 0 && i % reportEveryNthEvent == 0){ - printf( "Processing Event %d...\n", i ); - } - // run qa subroutines here - // qaMomentumResolution(); - qaFCSTrackMatch(); - } -} - - - -void qa( TString filename = "fwdtree.root" ){ - setupRead( filename ); - TFile * fOut = new TFile( "QuickQA.root", "RECREATE" ); - fOut->cd(); - eventLoop(5000, 100); - fOut->Write(); - // writeHistograms(); - return; - //loop over the events - int nEvents = t->GetEntries(); - if (nEvents > 1000) nEvents = 1000; - for ( int i = 0; i < nEvents; i++ ){ - t->GetEntry(i); - for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ - StMuFwdTrack *track = fwdTracks->At(j); - printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); - - StMuFwdTrackProjection projWCAL; - track->getProjectionFor(kFcsWcalId, projWCAL); - printf("Projection @ WCAL: det=%d, x=%f, y=%f, z=%f\n", projWCAL.mDetId, projWCAL.mXYZ.X(), projWCAL.mXYZ.Y(), projWCAL.mXYZ.Z()); - - - StMuFwdTrackProjection projHCAL; - track->getProjectionFor(kFcsHcalId, projHCAL); - printf("Projection @ HCAL: det=%d, x=%f, y=%f, z=%f\n", projHCAL.mDetId, projHCAL.mXYZ.X(), projHCAL.mXYZ.Y(), projHCAL.mXYZ.Z()); - - // loop over WCAL clusters - for ( int k = 0; k < wcal->GetEntries(); k++ ){ - FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); - - printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); - - } - - - // loop over WCAL clusters - for ( int k = 0; k < wcal->GetEntries(); k++ ){ - FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); - - printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); - - } - - } - } - cout << "Processed: " << t->GetEntries() << " entries" << endl; -} diff --git a/StRoot/StFwdTrackMaker/macro/shell.C b/StRoot/StFwdTrackMaker/macro/shell.C deleted file mode 100755 index f5561a82137..00000000000 --- a/StRoot/StFwdTrackMaker/macro/shell.C +++ /dev/null @@ -1,9 +0,0 @@ - - - -void shell(){ - gSystem->Load( "libStarRoot.so" ); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - gROOT->LoadMacro("bfc.C"); - bfc(-1, "StEvent cmudst fwdTrack", ""); -} \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/close.C b/StRoot/StFwdTrackMaker/macro/sim/close.C deleted file mode 100755 index 5ee794cf871..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/close.C +++ /dev/null @@ -1,108 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-50}','${3:-0.001}','${4:-0.001}','${5:-3.0}','${6:-0.004}','${7:-0}',"'${8:- }'")'; exit $? -// that is a valid shebang to run script as executable, but with only one arg - - -// Run very fast fwd tracking -// generate some input data using genfzd - -TFile *output = 0; - -void close( char *inFile = "sim.fzd", - int n = 100000, // nEvents to run - double primaryVertexSigmaXY = 0.001, - double primaryVertexSigmaZ = 0.001, - double fstRasterR = 3.0, - double fstRasterPhi = 0.0040906154, - int numFttToUse = 0, - TString note = "" - ) { - // report all of the parameters passed in - cout << "inFile = " << inFile << endl; - cout << "nEvents = " << n << endl; - TString mOutput = TString::Format( - "closure_PV_XY%dum_Z%dum_FST_R%.2fcm_PHI%0.3frad_NumFTT%d%s", - (int)(primaryVertexSigmaXY*1e4), - (int)(primaryVertexSigmaZ*1e4), - fstRasterR, - fstRasterPhi, - numFttToUse, - note.Data() - ); - // replace all "." with "p" in the output file name - mOutput.ReplaceAll(".", "p"); - mOutput += ".root"; - cout << "Output file = " << mOutput.Data() << endl; - - // Setup the chain for reading an FZD - TString _chain; - _chain = "fzin sdt20211016 MakeEvent bigbig evout cmudst tree"; - - - gSystem->Load( "libStarRoot.so" ); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - gROOT->LoadMacro("bfc.C"); - bfc(-1, _chain, inFile); - - gSystem->Load( "libStFttSimMaker" ); - gSystem->Load( "libStFcsTrackMatchMaker" ); - - gSystem->Load( "libMathMore.so" ); - gSystem->Load( "libStarGeneratorUtil" ); - - gSystem->Load("libXMLIO.so"); - gSystem->Load("libgenfit2.so"); - gSystem->Load("libKiTrack.so"); - gSystem->Load("StarGeneratorUtil"); - // gSystem->Load("libMathMore.so"); - gSystem->Load("StEventUtilities"); - gSystem->Load("StEpdUtil"); - gSystem->Load("StFwdTrackMaker"); - - gSystem->Load("StFwdUtils.so"); - - - // Configure the Forward Tracker - StFwdClosureMaker * fwdClosure = new StFwdClosureMaker(); - fwdClosure->SetDebug(1); - fwdClosure->mMaxIt = 4; - - fwdClosure->mBlowUp = 1e3; - fwdClosure->mPVal = 1e-3; - fwdClosure->mRelChi2 = 1e-3; - - fwdClosure->mFttMode = StFwdClosureMaker::kStrip; - - fwdClosure->mPrimaryVertexSigXY = primaryVertexSigmaXY; - fwdClosure->mPrimaryVertexSigZ = primaryVertexSigmaZ; - fwdClosure->mRasterR = fstRasterR; - fwdClosure->mRasterPhi = fstRasterPhi; - fwdClosure->mNumFttToUse = numFttToUse; - fwdClosure->mOutFile = mOutput; - fwdClosure->SetDebug(1); - - chain->AddBefore("MuDst", fwdClosure); - - - StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); - - // if (muDstMaker){ - // StFwdQAMaker *fwdQA = new StFwdQAMaker(); - // fwdQA->SetDebug(2); - // chain->AddAfter("MuDst", fwdQA); - // } - -chain_loop: - chain->Init(); - - //_____________________________________________________________________________ - // - // MAIN EVENT LOOP - //_____________________________________________________________________________ - for (int i = 0; i < n; i++) { - cout << "--------->START EVENT: " << i << endl; - chain->Clear(); - if (kStOK != chain->Make()) - break; - cout << "<---------- END EVENT" << endl; - } // event loop -} diff --git a/StRoot/StFwdTrackMaker/macro/sim/fast.C b/StRoot/StFwdTrackMaker/macro/sim/fast.C deleted file mode 100755 index 7cfc9ba7357..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/fast.C +++ /dev/null @@ -1,145 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-5}')'; exit $? -// that is a valid shebang to run script as executable, but with only one arg - - -// Run very fast fwd tracking -// generate some input data using genfzd - -TFile *output = 0; - -void fast( char *inFile = "sim.fzd", - int n = 1000, // nEvents to run - bool useFstForSeedFinding = true, // use FTT (default) or FST for track finding - bool enableTrackRefit = true, // Enable track refit (default off) - bool realisticSim = true, // enables data-like mode, real track finding and fitting without MC seed - bool useZeroB = false - ) { - // report all of the parameters passed in - cout << "inFile = " << inFile << endl; - cout << "n = " << n << endl; - cout << "useFstForSeedFinding = " << useFstForSeedFinding << endl; - cout << "enableTrackRefit = " << enableTrackRefit << endl; - cout << "realisticSim = " << realisticSim << endl; - cout << "useZeroB = " << useZeroB << endl; - const char *geom = ""; - TString _geom = geom; - - // Switches for common options - bool SiIneff = false; - bool useConstBz = false; - bool useFCS = true; - - // to use the geom cache (skip agml build which is faster) - // set the _geom string to "" and make sure the cache file ("fGeom.root") is present - // _geom = ""; - - // Setup the chain for reading an FZD - TString _chain; - - _chain = Form("fzin %s sdt20211016 fwdTrack MakeEvent bigbig evout cmudst tree", _geom.Data() ); - - - gSystem->Load( "libStarRoot.so" ); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - gROOT->LoadMacro("bfc.C"); - bfc(-1, _chain, inFile); - - gSystem->Load( "libStFttSimMaker" ); - gSystem->Load( "libStFcsTrackMatchMaker" ); - - gSystem->Load( "libMathMore.so" ); - gSystem->Load( "libStarGeneratorUtil" ); - - - gSystem->Load("StFwdUtils.so"); - - - - // Configure the Forward Tracker - StFwdTrackMaker * fwdTrack = (StFwdTrackMaker*) chain->GetMaker( "fwdTrack" ); - - if ( fwdTrack ){ - fwdTrack->SetDebug(1); - // config file set here for ideal simulation - if (!realisticSim){ - cout << "Configured for ideal simulation (MC finding + MC mom seed)" << endl; - fwdTrack->setConfigForIdealSim( ); - } else { - cout << "Configured for realistic simulation" << endl; - fwdTrack->setConfigForRealisticSim( ); - cout << "Configured for realistic simulation DONE" << endl; - } - - if ( _geom == "" ){ - cout << "Using the Geometry cache: fGeom.root" << endl; - fwdTrack->setGeoCache( "fGeom.root" ); - } - - // choose - if (useFstForSeedFinding) - fwdTrack->setSeedFindingWithFst(); - else { // default for this true/false option - fwdTrack->setSeedFindingWithFtt(); - } - // other options - // fwdTrack->setSeedFindingWithFtt(); - // fwdTrack->setSeedFindingWithFstFttSequential(); - // fwdTrack->setSeedFindingWithFstFttSimultaneous(); - - - fwdTrack->setOutputFilename( TString::Format( "%s.output.root", inFile ).Data() ); - fwdTrack->SetVisualize( false ); - fwdTrack->SetDebug(); - fwdTrack->setTrackRefit( enableTrackRefit ); - fwdTrack->setConstB( useConstBz ); - - if ( useZeroB ){ - cout << "Setting B = 0" << endl; - fwdTrack->setZeroB( true ); - } - - bool doFitQA = true; - if ( doFitQA ){ - StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); - fwdFitQA->SetDebug(); - TString fitqaoutname(gSystem->BaseName(inFile)); - fitqaoutname.ReplaceAll(".fzd", ".FwdFitQA.root"); - fwdFitQA->setOutputFilename( fitqaoutname ); - chain->AddAfter("fwdTrack", fwdFitQA); - } - cout << "fwd tracker setup" << endl; - } - - StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); - - if (muDstMaker){ - StFwdQAMaker *fwdQA = new StFwdQAMaker(); - fwdQA->SetDebug(2); - TString fwdqaname(gSystem->BaseName(inFile)); - fwdqaname.ReplaceAll(".fzd", ".FwdTree.root"); - fwdQA->setTreeFilename(fwdqaname); - chain->AddAfter("MuDst", fwdQA); - } - - // The PicoDst - gSystem->Load("libStPicoEvent"); - gSystem->Load("libStPicoDstMaker"); - StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); - cout << "picoMk = " << picoMk << endl; - picoMk->setVtxMode(StPicoDstMaker::Default); - -chain_loop: - chain->Init(); - - //_____________________________________________________________________________ - // - // MAIN EVENT LOOP - //_____________________________________________________________________________ - for (int i = 0; i < n; i++) { - cout << "--------->START EVENT: " << i << endl; - chain->Clear(); - if (kStOK != chain->Make()) - break; - cout << "<---------- END EVENT" << endl; - } // event loop -} diff --git a/StRoot/StFwdTrackMaker/macro/sim/gen b/StRoot/StFwdTrackMaker/macro/sim/gen deleted file mode 100755 index d8629b8b188..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/gen +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/bash - -nEvents=${1:-1000} #num events -pid=${2:-5} # default muon - -echo "Usage:\n sim/gen " -echo "nEvents=${nEvents}" - -strongrandom=`od -vAn -N3 -tu4 < /dev/urandom | tr -d '[:space:]'` - -if [ -f "sim.fzd" ] ; then - echo "sim.fzd already exists, skipping" -else - echo "strong random ${strongrandom}" - echo root4star -b -q -l 'sim/gen.C( '"${nEvents}"','"${strongrandom}"')' - time root4star -b -q -l 'sim/gen.C( '"${nEvents}"','"${strongrandom}"')' -fi diff --git a/StRoot/StFwdTrackMaker/macro/sim/gen.C b/StRoot/StFwdTrackMaker/macro/sim/gen.C old mode 100755 new mode 100644 index b5d2b16ba43..5056662f861 --- a/StRoot/StFwdTrackMaker/macro/sim/gen.C +++ b/StRoot/StFwdTrackMaker/macro/sim/gen.C @@ -1,4 +1,3 @@ -//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? // macro to instantiate the Geant3 from within // STAR C++ framework and get the starsim prompt // To use it do @@ -19,24 +18,7 @@ StarKinematics *kinematics = 0; TH1F* hNumHits = 0; TString nameParticle = "mu+"; -int numParticles = 1; -float minPt = 0.0; -float maxPt = 1.0; -float minEta = 2.5; -float maxEta = 4.00; -float minPhi = 0.0; -float maxPhi = 2.0 * TMath::Pi(); - -float vtxX = 0.0; -float vtxY = 0.0; -float vtxZ = 0.0; - -float vtxSigmaX = 0.0001; -float vtxSigmaY = 0.0001; -float vtxSigmaZ = 0.0001; - -TString fzdFilename = "sim.fzd"; -TString primaryName = "sim.root"; +float numParticles = 5; // ---------------------------------------------------------------------------- void geometry( TString tag, Bool_t agml=true ) @@ -53,46 +35,58 @@ void command( TString cmd ) geant_maker -> Do( cmd ); } // ---------------------------------------------------------------------------- -void trig_event( Int_t i ) -{ - if ( gRandom->Rndm() > 0.5 ) { - nameParticle = "mu+"; - } else { - nameParticle = "mu-"; - } - kinematics->Kine( numParticles, nameParticle.Data(), minPt, maxPt, minEta, maxEta, minPhi, maxPhi ); -} -// ---------------------------------------------------------------------------- void trig( Int_t n=1 ) { + + for ( Int_t i=0; iClear(); - trig_event( i ); + + kinematics->Kine( numParticles, nameParticle.Data(), 0.2, 5.0, 2.0, 4.50 ); + // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); + // Generate the event chain->Make(); + + TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); + if ( hits ) { + double nhits = hits->GetNRows(); + hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); + std::cout << "N hits = " << nhits << std::endl; + } + + // Print the event + // command("gprint hits stgh"); + } } // ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- void Kinematics() { - + // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); gSystem->Load( "libKinematics.so"); kinematics = new StarKinematics(); + _primary->AddGenerator(kinematics); } // ---------------------------------------------------------------------------- -void gen( Int_t nevents=1000, Int_t rngSeed=12352342 ) -{ +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) +{ - cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; + cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; gSystem->Load( "libStarRoot.so" ); gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); gROOT->ProcessLine(".L bfc.C"); { - TString simple = "sdt20211016 y2024 geant gstar usexgeom agml "; + TString simple = "sdt20211016 y2023 geant gstar usexgeom agml "; bfc(0, simple ); } @@ -102,7 +96,7 @@ void gen( Int_t nevents=1000, Int_t rngSeed=12352342 ) gSystem->Load( "StarGeneratorEvent.so" ); gSystem->Load( "StarGeneratorBase.so" ); - gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libMathMore.so" ); gSystem->Load( "xgeometry.so" ); // Setup RNG seed and map all ROOT TRandom here @@ -116,7 +110,7 @@ void gen( Int_t nevents=1000, Int_t rngSeed=12352342 ) // StarPrimaryMaker * _primary = new StarPrimaryMaker(); { - _primary -> SetFileName( primaryName ); + _primary -> SetFileName( "sim.root"); chain -> AddBefore( "geant", _primary ); } @@ -126,15 +120,19 @@ void gen( Int_t nevents=1000, Int_t rngSeed=12352342 ) // Initialize primary event generator and all sub makers // _primary -> Init(); - _primary->SetSigma( vtxSigmaX, vtxSigmaY, vtxSigmaZ ); // 1mm x 1mm x 1mm smearing at the vertex - _primary->SetVertex(vtxX, vtxY, vtxZ ); + _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex + _primary->SetVertex(0.0, 0.0, 0.0 ); // // Setup geometry and set starsim to use agusread for input // //geometry("y2012"); command("gkine -4 0"); - command( TString::Format("gfile o %s", fzdFilename.Data()) ); + command("gfile o sim.fzd"); + + + hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); + // hNumHits->SetBit(TH1::kCanRebin); // command( "DCAY 0" ); @@ -152,14 +150,19 @@ void gen( Int_t nevents=1000, Int_t rngSeed=12352342 ) // command( "MULS 0" ); // command( "STRA 0" ); // command( "physi" ); - + // // Trigger on nevents // - // StarMagField::setConstBz(true); trig( nevents ); + // TFile * f = new TFile( "gen.root", "RECREATE" ); + // f->cd(); + // hNumHits->Write(); + // f->Write(); + command("call agexit"); // Make sure that STARSIM exits properly } // ---------------------------------------------------------------------------- + diff --git a/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-fst-seed b/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-fst-seed deleted file mode 100755 index 601b8f911aa..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-fst-seed +++ /dev/null @@ -1,2 +0,0 @@ -nEvents=${1:-10} #num events -root4star -b -q -l 'sim/sim.C('${nEvents}', "StFwdTrackMaker_ideal_sim_fst_seed.root", true, true, false )' >& LOG_IDEAL_SIM_FST_SEED.log \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-ftt-seed b/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-ftt-seed deleted file mode 100755 index 2613cef1b98..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/ideal-sim-ftt-seed +++ /dev/null @@ -1,2 +0,0 @@ -nEvents=${1:-10} #num events -root4star -b -q -l 'sim/sim.C('${nEvents}', "StFwdTrackMaker_ideal_sim_ftt_seed.root", false, true, false )' >& LOG_IDEAL_SIM_FTT_SEED.log \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/jpsi b/StRoot/StFwdTrackMaker/macro/sim/jpsi deleted file mode 100755 index 656d73c0874..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/jpsi +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/bash - -nEvents=${1:-10} #num events - -echo "Usage:\n sim/jpsi " -echo "nEvents=${nEvents}" - -strongrandom=`od -vAn -N3 -tu4 < /dev/urandom | tr -d '[:space:]'` - -if [ -f "jpsi.fzd" ] ; then - echo "jpsi.fzd already exists, skipping" -else - echo "strong random ${strongrandom}" - echo root4star -b -q -l 'sim/jpsi.C( '"${nEvents}"','"${strongrandom}"')' - time root4star -b -q -l 'sim/jpsi.C( '"${nEvents}"','"${strongrandom}"')' -fi diff --git a/StRoot/StFwdTrackMaker/macro/sim/jpsi.C b/StRoot/StFwdTrackMaker/macro/sim/jpsi.C deleted file mode 100755 index bc4f936d29e..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/jpsi.C +++ /dev/null @@ -1,225 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? -// macro to instantiate the Geant3 from within -// STAR C++ framework and get the starsim prompt -// To use it do -// root4star starsim.C - -class St_geant_Maker; -St_geant_Maker *geant_maker = 0; - -class StarGenEvent; -StarGenEvent *event = 0; - -class StarPrimaryMaker; -StarPrimaryMaker *_primary = 0; - -class StarKinematics; -StarKinematics *kinematics = 0; - - -TH1F* hMll = 0; -bool decayJPsiToElectrons = false; -float numParticles = 1; - -// ---------------------------------------------------------------------------- -void geometry( TString tag, Bool_t agml=true ) -{ - TString cmd = "DETP GEOM "; cmd += tag + " field=-5.0"; - if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); - geant_maker -> LoadGeometry(cmd); - // if ( agml ) command("gexec $STAR_LIB/libxgeometry.so"); -} -// ---------------------------------------------------------------------------- -void command( TString cmd ) -{ - if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); - geant_maker -> Do( cmd ); -} -// ---------------------------------------------------------------------------- -void trig( Int_t n=1 ) -{ - - - for ( Int_t i=0; iClear(); - - //(Momentum, Energy units are Gev/C, GeV) - Double_t masses[2] = { 0.00051099895000, 0.00051099895000} ; - - if (!decayJPsiToElectrons){ - masses[0] = 0.1056583755; - masses[1] = 0.1056583755; - } - - TGenPhaseSpace genEvent; - TLorentzVector W; - // W.SetPtEtaPhiM( 0.0, 100.0, 0, 3.096 ); - W.SetXYZM( 0, 0, 30, 3.096 ); - genEvent.SetDecay(W, 2, masses); - - TLorentzVector lv; - for ( int j = 0; j < numParticles; j++ ){ - Double_t weight = genEvent.Generate(); - TLorentzVector *pElectron = genEvent.GetDecay(0); - TLorentzVector *pPositron = genEvent.GetDecay(1); - lv = *pElectron + *pPositron; - - StarGenParticle *ele; - if ( decayJPsiToElectrons ) - ele = kinematics->AddParticle( "e-" ); - else - ele = kinematics->AddParticle( "mu-" ); - ele->SetPx(pElectron->Px()); - ele->SetPy(pElectron->Py()); - ele->SetPz(pElectron->Pz()); - ele->SetMass( masses[0] ); - - StarGenParticle *pos; - if ( decayJPsiToElectrons ) - pos = kinematics->AddParticle( "e+" ); - else - pos = kinematics->AddParticle( "mu+" ); - pos->SetPx(pPositron->Px()); - pos->SetPy(pPositron->Py()); - pos->SetPz(pPositron->Pz()); - pos->SetMass( masses[0] ); - - hMll->Fill( lv.M() ); - - cout << "ele eta = " << pElectron->Eta() << endl; - cout << "pos eta = " << pPositron->Eta() << endl; - } - - - // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); - - // Generate the event - chain->Make(); - - // TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); - // if ( hits ) { - // double nhits = hits->GetNRows(); - // hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); - // std::cout << "N hits = " << nhits << std::endl; - // } - - // Print the event - // command("gprint hits stgh"); - - } -} -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -void Kinematics() -{ - - // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); - gSystem->Load( "libKinematics.so"); - kinematics = new StarKinematics(); - - _primary->AddGenerator(kinematics); -} -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -void jpsi( Int_t nevents=10000, Int_t rngSeed=12352342, bool decayToElectrons = true ) -{ - - hMll = new TH1F("hMll",";Mll;counts [10MeV]", 200, 2.0, 4.0 ); - decayJPsiToElectrons = decayToElectrons; - cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; - if ( decayToElectrons ){ - cout << "Simulating J/psi->e+e-" << endl; - } else { - cout << "Simulating J/psi->mu+mu-" << endl; - } - gSystem->Load( "libStarRoot.so" ); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - - gROOT->ProcessLine(".L bfc.C"); - { - TString simple = "sdt20211016 y2024 geant gstar usexgeom agml "; - bfc(0, simple ); - } - - gSystem->Load( "libVMC.so"); - - gSystem->Load( "StarGeneratorUtil.so" ); - gSystem->Load( "StarGeneratorEvent.so" ); - gSystem->Load( "StarGeneratorBase.so" ); - - gSystem->Load( "libMathMore.so" ); - gSystem->Load( "xgeometry.so" ); - - - - // Setup RNG seed and map all ROOT TRandom here - StarRandom::seed( rngSeed ); - StarRandom::capture(); - - // - // Create the primary event generator and insert it - // before the geant maker - // - // StarPrimaryMaker * - _primary = new StarPrimaryMaker(); - { - _primary -> SetFileName( "jpsi.root"); - chain -> AddBefore( "geant", _primary ); - } - - Kinematics(); - - // - // Initialize primary event generator and all sub makers - // - _primary -> Init(); - _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex - _primary->SetVertex(0.0, 0.0, 0.0 ); - - // - // Setup geometry and set starsim to use agusread for input - // - //geometry("y2012"); - command("gkine -4 0"); - command("gfile o jpsi.fzd"); - - - hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); - // hNumHits->SetBit(TH1::kCanRebin); - - - // command( "DCAY 0" ); - // command( "ANNI 0" ); - // command( "BREM 0" ); - // command( "COMP 0" ); - // command( "HADR 0" ); - // command( "MUNU 0" ); - // command( "PAIR 0" ); - // command( "PFIS 0" ); - // command( "PHOT 0" ); - // command( "RAYL 0" ); - // command( "LOSS 4" ); - // command( "DRAY 0" ); - // command( "MULS 0" ); - // command( "STRA 0" ); - // command( "physi" ); - - // - // Trigger on nevents - // - trig( nevents ); - - TFile * f = new TFile( "jpsi_gen.root", "RECREATE" ); - f->cd(); - hMll->Write(); - f->Write(); - - command("call agexit"); // Make sure that STARSIM exits properly - -} -// ---------------------------------------------------------------------------- - diff --git a/StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C b/StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C deleted file mode 100644 index 233a0d37a91..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/jpsi_ana.C +++ /dev/null @@ -1,181 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'('$1')'; exit $? -// that is a valid shebang to run script as executable, but with only one arg - - -// Run very fast fwd tracking -// generate some input data using genfzd - -TFile *output = 0; - -void jpsi_ana( int n = 5, // nEvents to run - string outputName = "stFwdTrackMaker_ideal_jpsi.root", - bool useFstForSeedFinding = false, // use FTT (default) or FST for track finding - bool enableTrackRefit = true, // Enable track refit (default off) - bool realisticSim = false, // enables data-like mode, real track finding and fitting without MC seed - char *inFile = "jpsi.fzd" - ) { - cout << "Running " << n << " events from " << inFile << endl; - const char *geom = "y2023"; - TString _geom = geom; - - // Switches for common options - bool SiIneff = false; - bool useConstBz = false; - bool useFCS = true; - - - // Setup the chain for reading an FZD - TString _chain; - if ( useFCS ) - _chain = Form("fzin %s sdt20211016 fstFastSim fcsSim fcsWFF fcsCluster fwdTrack MakeEvent StEvent ReverseField agml usexgeom bigbig evout cmudst tree", _geom.Data()); - else - _chain = Form("fzin %s sdt20211016 MakeEvent StEvent ReverseField agml usexgeom bigbig fstFastSim fcsSim fwdTrack evout cmudst tree", _geom.Data()); - - gSystem->Load( "libStarRoot.so" ); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - gROOT->LoadMacro("bfc.C"); - bfc(-1, _chain, inFile); - - if ( useConstBz ) - StarMagField::setConstBz(true); - - gSystem->Load( "libStFttSimMaker" ); - gSystem->Load( "libStFcsTrackMatchMaker" ); - - // FCS setup, if included - if (useFCS) { - - StFcsDbMaker* fcsdbmkr = (StFcsDbMaker*) chain->GetMaker("fcsDbMkr"); - cout << "fcsdbmkr="<GetDataSet("fcsDb"); - cout << "fcsdb="<setDbAccess(1); - - // Configure FCS simulator - StFcsFastSimulatorMaker *fcssim = (StFcsFastSimulatorMaker*) chain->GetMaker("fcsSim"); - fcssim->setDebug(1); - //fcssim->setLeakyHcal(0); - - StFcsWaveformFitMaker *fcsWFF= (StFcsWaveformFitMaker*) chain->GetMaker("StFcsWaveformFitMaker"); - fcsWFF->setEnergySelect(0); - - StFcsClusterMaker *fcsclu = (StFcsClusterMaker*) chain->GetMaker("StFcsClusterMaker"); - fcsclu->setDebug(1); - } - - // { - gSystem->Load("StFwdUtils.so"); - // StFwdJPsiMaker *fwdJPsi = new StFwdJPsiMaker(); - // fwdJPsi->SetDebug(); - // chain->AddMaker(fwdJPsi); - // goto chain_loop; - // } - - - // Configure FST FastSim - TString qaoutname(gSystem->BaseName(inFile)); - qaoutname.ReplaceAll(".fzd", ".FastSimu.QA.root"); - StFstFastSimMaker *fstFastSim = (StFstFastSimMaker*) chain->GetMaker( "fstFastSim" );; - - if (SiIneff) - fstFastSim->SetInEfficiency(0.1); // inefficiency of Si - - fstFastSim->SetQAFileName(qaoutname); - - cout << "Adding StFstFastSimMaker to chain" << endl; - chain->AddMaker(fstFastSim); - - - // Configure the Forward Tracker - StFwdTrackMaker * fwdTrack = (StFwdTrackMaker*) chain->GetMaker( "fwdTrack" ); - - // config file set here for ideal simulation - if (!realisticSim){ - cout << "Configured for ideal simulation (MC finding + MC mom seed)" << endl; - fwdTrack->setConfigForIdealSim( ); - } else { - cout << "Configured for realistic simulation" << endl; - fwdTrack->setConfigForRealisticSim( ); - cout << "Configured for realistic simulation DONE" << endl; - } - - if (useFstForSeedFinding) - fwdTrack->setSeedFindingWithFst(); - else - fwdTrack->setSeedFindingWithFtt(); - - fwdTrack->setTrackRefit( enableTrackRefit ); - fwdTrack->setOutputFilename( outputName ); - fwdTrack->SetGenerateTree( true ); - fwdTrack->SetGenerateHistograms( true ); - fwdTrack->SetDebug(); - - cout << "fwd tracker setup" << endl; - - - if (!useFCS){ - StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); - fwdAna->SetDebug(); - chain->AddAfter("fwdTrack", fwdAna); - } - - StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); - if (useFCS) { - // FwdTrack and FcsCluster assciation - gSystem->Load("StFcsTrackMatchMaker"); - StFcsTrackMatchMaker *match = new StFcsTrackMatchMaker(); - match->setMaxDistance(6,10); - match->setFileName("fcstrk.root"); - match->SetDebug(); - chain->AddMaker(match); - - StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); - fwdAna->SetDebug(); - chain->AddAfter("FcsTrkMatch", fwdAna); - - StFwdJPsiMaker *fwdJPsi = new StFwdJPsiMaker(); - fwdJPsi->SetDebug(); - chain->AddAfter("FcsTrkMatch", fwdJPsi); - - gSystem->Load("StFcsDiLeptonMaker"); - StFcsDiLeptonMaker *dilep = new StFcsDiLeptonMaker; - //TString dilepfile(outfile); dilepfile.ReplaceAll(".root",".dilep.root"); - dilep->setFileName("dilep.root");//dilepfile.Data()); - //chain->AddAfter("FcsTrkMatch", dilep); - - // Produce MuDst output - chain->AddAfter( "FcsTrkMatch", muDstMaker ); - } else { - chain->AddAfter( "fwdAna", muDstMaker ); - } - - - -chain_loop: - chain->Init(); - - //_____________________________________________________________________________ - // - // MAIN EVENT LOOP - //_____________________________________________________________________________ - for (int i = 0; i < n; i++) { - - cout << "--------->START EVENT: " << i << endl; - - chain->Clear(); - if (kStOK != chain->Make()) - break; - - - // StMuDst * mds = muDstMaker->muDst(); - // StMuFwdTrackCollection * ftc = mds->muFwdTrackCollection(); - // cout << "Number of StMuFwdTracks: " << ftc->numberOfFwdTracks() << endl; - // for ( size_t iTrack = 0; iTrack < ftc->numberOfFwdTracks(); iTrack++ ){ - // StMuFwdTrack * muFwdTrack = ftc->getFwdTrack( iTrack ); - // cout << "muFwdTrack->mPt = " << muFwdTrack->momentum().Pt() << endl; - - // } - - cout << "<---------- END EVENT" << endl; - } // event loop -} diff --git a/StRoot/StFwdTrackMaker/macro/sim/lambda.C b/StRoot/StFwdTrackMaker/macro/sim/lambda.C deleted file mode 100755 index 23af6349857..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/lambda.C +++ /dev/null @@ -1,191 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? -// macro to instantiate the Geant3 from within -// STAR C++ framework and get the starsim prompt -// To use it do -// root4star starsim.C - -class St_geant_Maker; -St_geant_Maker *geant_maker = 0; - -class StarGenEvent; -StarGenEvent *event = 0; - -class StarPrimaryMaker; -StarPrimaryMaker *_primary = 0; - -class StarKinematics; -StarKinematics *kinematics = 0; - - -TH1F* hMll = 0; -float numParticles = 1; - -// ---------------------------------------------------------------------------- -void geometry( TString tag, Bool_t agml=true ) -{ - TString cmd = "DETP GEOM "; cmd += tag + " field=-5.0"; - if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); - geant_maker -> LoadGeometry(cmd); - // if ( agml ) command("gexec $STAR_LIB/libxgeometry.so"); -} -// ---------------------------------------------------------------------------- -void command( TString cmd ) -{ - if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); - geant_maker -> Do( cmd ); -} -// ---------------------------------------------------------------------------- -void trig( Int_t n=1 ) -{ - - - for ( Int_t i=0; iClear(); - - //(Momentum, Energy units are Gev/C, GeV) - Double_t masses[2] = { 0.13957, 0.938} ; - - TGenPhaseSpace genEvent; - TLorentzVector W; - // W.SetPtEtaPhiM( 0.0, 100.0, 0, 3.096 ); - W.SetXYZM( 0, 0, 5, 1.11568 ); - genEvent.SetDecay(W, 2, masses); - - TLorentzVector lv; - for ( int j = 0; j < numParticles; j++ ){ - Double_t weight = genEvent.Generate(); - TLorentzVector *pPion = genEvent.GetDecay(0); - TLorentzVector *pProton = genEvent.GetDecay(1); - lv = *pPion + *pProton; - - StarGenParticle *pion; - pion = kinematics->AddParticle( "pi-" ); - - pion->SetPx(pPion->Px()); - pion->SetPy(pPion->Py()); - pion->SetPz(pPion->Pz()); - pion->SetMass( masses[0] ); - - StarGenParticle *proton; - proton = kinematics->AddParticle( "p" ); - - - proton->SetPx(pProton->Px()); - proton->SetPy(pProton->Py()); - proton->SetPz(pProton->Pz()); - proton->SetMass( masses[1] ); - - hMll->Fill( lv.M() ); - - cout << "pion eta = " << pPion->Eta() << endl; - cout << "proton eta = " << pProton->Eta() << endl; - } - - - // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); - - // Generate the event - chain->Make(); - - // TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); - // if ( hits ) { - // double nhits = hits->GetNRows(); - // hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); - // std::cout << "N hits = " << nhits << std::endl; - // } - - // Print the event - // command("gprint hits stgh"); - - } -} -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -void Kinematics() -{ - - // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); - gSystem->Load( "libKinematics.so"); - kinematics = new StarKinematics(); - - _primary->AddGenerator(kinematics); -} -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -void lambda( Int_t nevents=100, Int_t rngSeed=12352342 ) -{ - hMll = new TH1F("hMll",";Mll;counts [10MeV]", 200, 2.0, 4.0 ); - cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; - cout << "Simulating J/psi->e+e-" << endl; - - gSystem->Load( "libStarRoot.so" ); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - - gROOT->ProcessLine(".L bfc.C"); - { - TString simple = "sdt20211016 y2023 geant gstar usexgeom agml "; - bfc(0, simple ); - } - - gSystem->Load( "libVMC.so"); - - gSystem->Load( "StarGeneratorUtil.so" ); - gSystem->Load( "StarGeneratorEvent.so" ); - gSystem->Load( "StarGeneratorBase.so" ); - - gSystem->Load( "libMathMore.so" ); - gSystem->Load( "xgeometry.so" ); - - // Setup RNG seed and map all ROOT TRandom here - StarRandom::seed( rngSeed ); - StarRandom::capture(); - - // - // Create the primary event generator and insert it - // before the geant maker - // - // StarPrimaryMaker * - _primary = new StarPrimaryMaker(); - { - _primary -> SetFileName( "lambda_fwd_gun.root"); - chain -> AddBefore( "geant", _primary ); - } - - Kinematics(); - - // - // Initialize primary event generator and all sub makers - // - _primary -> Init(); - _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex - _primary->SetVertex(0.0, 0.0, 0.0 ); - - // - // Setup geometry and set starsim to use agusread for input - // - //geometry("y2012"); - command("gkine -4 0"); - command("gfile o lambda_fwd_gun.fzd"); - - - hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); - - // - // Trigger on nevents - // - trig( nevents ); - - TFile * f = new TFile( "lambda_gen.root", "RECREATE" ); - f->cd(); - hMll->Write(); - f->Write(); - - command("call agexit"); // Make sure that STARSIM exits properly - -} -// ---------------------------------------------------------------------------- - diff --git a/StRoot/StFwdTrackMaker/macro/sim/real-sim-fst-seed b/StRoot/StFwdTrackMaker/macro/sim/real-sim-fst-seed deleted file mode 100755 index 6c970f1336b..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/real-sim-fst-seed +++ /dev/null @@ -1,2 +0,0 @@ -nEvents=${1:-10} #num events -root4star -b -q -l 'sim/sim.C('${nEvents}', "StFwdTrackMaker_real_sim_fst_seed.root", true, true, true )' >& LOG_REAL_SIM_FST_SEED.log \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/real-sim-ftt-seed b/StRoot/StFwdTrackMaker/macro/sim/real-sim-ftt-seed deleted file mode 100755 index f66a71321bd..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/real-sim-ftt-seed +++ /dev/null @@ -1,2 +0,0 @@ -nEvents=${1:-10} #num events -root4star -b -q -l 'sim/sim.C('${nEvents}', "StFwdTrackMaker_real_sim_ftt_seed.root", false, true, true )' >& LOG_REAL_SIM_FTT_SEED.log \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/sim/sim.C b/StRoot/StFwdTrackMaker/macro/sim/sim.C deleted file mode 100755 index beef7dfeb16..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/sim.C +++ /dev/null @@ -1,242 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-2000}')'; exit $? -// that is a valid shebang to run script as executable, but with only one arg - - -// Run very fast fwd tracking -// generate some input data using genfzd - -TFile *output = 0; - -void sim( char *inFile = "sim.fzd", - int n = 100, // nEvents to run - bool useFstForSeedFinding = true, // use FTT (default) or FST for track finding - bool enableTrackRefit = true, // Enable track refit (default off) - bool realisticSim = true, // enables data-like mode, real track finding and fitting without MC seed - bool useZeroB = false - ) { - // report all of the parameters passed in - cout << "inFile = " << inFile << endl; - cout << "n = " << n << endl; - cout << "useFstForSeedFinding = " << useFstForSeedFinding << endl; - cout << "enableTrackRefit = " << enableTrackRefit << endl; - cout << "realisticSim = " << realisticSim << endl; - cout << "useZeroB = " << useZeroB << endl; - const char *geom = "y2024 agml usexgeom"; - TString _geom = geom; - - // Switches for common options - bool SiIneff = false; - bool useConstBz = false; - bool useFCS = true; - - // use cached - _geom = ""; - - // to use the geom cache (skip agml build which is faster) - // set the _geom string to "" and make sure the cache file ("fGeom.root") is present - // _geom = ""; - - // Setup the chain for reading an FZD - TString _chain; - if ( useFCS ) - _chain = Form("fzin %s sdt20211016 fstFastSim fcsSim fcsWFF fcsCluster fwdTrack MakeEvent StEvent McEvent ReverseField bigbig evout cmudst tree", _geom.Data() ); - else - _chain = Form("fzin %s sdt20211016 MakeEvent StEvent ReverseField bigbig fstFastSim fcsSim fwdTrack evout cmudst tree", _geom.Data()); - - gSystem->Load( "libStarRoot.so" ); - gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); - gROOT->LoadMacro("bfc.C"); - bfc(-1, _chain, inFile); - - if ( useConstBz ) - StarMagField::setConstBz(true); - - gSystem->Load( "libStFttSimMaker" ); - gSystem->Load( "libStFcsTrackMatchMaker" ); - - gSystem->Load( "libMathMore.so" ); - gSystem->Load( "libStarGeneratorUtil" ); - - StFttFastSimMaker * fttSim = new StFttFastSimMaker(); - fttSim->SetDebug(); - chain->AddAfter("fcsSim", fttSim); - - // FCS setup, if included - if (useFCS) { - - StFcsDbMaker* fcsdbmkr = (StFcsDbMaker*) chain->GetMaker("fcsDbMkr"); - cout << "fcsdbmkr="<GetDataSet("fcsDb"); - fcsdb->forceFixGain(); - fcsdb->forceFixGainCorrection(); - cout << "fcsdb="<setDbAccess(1); - - // Configure FCS simulator - StFcsFastSimulatorMaker *fcssim = (StFcsFastSimulatorMaker*) chain->GetMaker("fcsSim"); - fcssim->setDebug(1); - //fcssim->setLeakyHcal(0); - - StFcsWaveformFitMaker *fcsWFF= (StFcsWaveformFitMaker*) chain->GetMaker("StFcsWaveformFitMaker"); - fcsWFF->setEnergySelect(0); - - StFcsClusterMaker *fcsclu = (StFcsClusterMaker*) chain->GetMaker("StFcsClusterMaker"); - fcsclu->setDebug(1); - } - - // { - gSystem->Load("StFwdUtils.so"); - // StFwdJPsiMaker *fwdJPsi = new StFwdJPsiMaker(); - // fwdJPsi->SetDebug(); - // chain->AddMaker(fwdJPsi); - // goto chain_loop; - // } - - - // Configure FST FastSim - TString qaoutname(gSystem->BaseName(inFile)); - qaoutname.ReplaceAll(".fzd", ".FastSimu.QA.root"); - StFstFastSimMaker *fstFastSim = (StFstFastSimMaker*) chain->GetMaker( "fstFastSim" );; - - if (SiIneff) - fstFastSim->SetInEfficiency(0.1); // inefficiency of Si - - fstFastSim->SetQAFileName(qaoutname); - - cout << "Adding StFstFastSimMaker to chain" << endl; - chain->AddAfter("fcsSim", fstFastSim); - - - // Configure the Forward Tracker - StFwdTrackMaker * fwdTrack = (StFwdTrackMaker*) chain->GetMaker( "fwdTrack" ); - - if ( fwdTrack ){ - fwdTrack->SetDebug(1); - // config file set here for ideal simulation - if (!realisticSim){ - cout << "Configured for ideal simulation (MC finding + MC mom seed)" << endl; - fwdTrack->setConfigForIdealSim( ); - } else { - cout << "Configured for realistic simulation" << endl; - fwdTrack->setConfigForRealisticSim( ); - cout << "Configured for realistic simulation DONE" << endl; - } - - if ( _geom == "" ){ - cout << "Using the Geometry cache: fGeom.root" << endl; - fwdTrack->setGeoCache( "fGeom.root" ); - } - - // choose - if (useFstForSeedFinding) - fwdTrack->setSeedFindingWithFst(); - else { // default for this true/false option - fwdTrack->setSeedFindingWithFtt(); - } - // other options - // fwdTrack->setSeedFindingWithFtt(); - // fwdTrack->setSeedFindingWithFstFttSequential(); - // fwdTrack->setSeedFindingWithFstFttSimultaneous(); - - fwdTrack->setTrackRefit( enableTrackRefit ); - fwdTrack->setConstB( useConstBz ); - fwdTrack->setOutputFilename( TString::Format( "%s.output.root", inFile ).Data() ); - fwdTrack->SetVisualize( false ); - fwdTrack->SetDebug(); - fwdTrack->setIncludePrimaryVertexInFit( false ); - - // fwdTrack->setTrackFittingOff(); - // fwdTrack->setUseMcSeedForFit(true); - // fwdTrack->setConfigKeyValue("") - if ( useZeroB ){ - cout << "Setting B = 0" << endl; - fwdTrack->setZeroB( true ); - } - bool doFitQA = true; - if ( doFitQA ){ - StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); - fwdFitQA->SetDebug(); - TString fitqaoutname(gSystem->BaseName(inFile)); - fitqaoutname.ReplaceAll(".fzd", ".FwdFitQA.root"); - fwdFitQA->setOutputFilename( fitqaoutname ); - chain->AddAfter("fwdTrack", fwdFitQA); - } - cout << "fwd tracker setup" << endl; - } - - bool doFwdAna = true; - if (!useFCS && doFwdAna ){ - StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); - fwdAna->SetDebug(); - chain->AddAfter("fwdTrack", fwdAna); - } - - - StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); - if (useFCS) { - // FwdTrack and FcsCluster assciation - gSystem->Load("StFcsTrackMatchMaker"); - StFcsTrackMatchMaker *match = new StFcsTrackMatchMaker(); - match->setMaxDistance(6,10); - match->setFileName("fcstrk.root"); - match->SetDebug(); - chain->AddMaker(match); - - if ( doFwdAna ){ - StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); - fwdAna->SetDebug(); - chain->AddAfter("FcsTrkMatch", fwdAna); - } - - // Produce MuDst output - if ( muDstMaker ) - chain->AddAfter( "FcsTrkMatch", muDstMaker ); - } else { - if ( muDstMaker ) - chain->AddAfter( "fwdAna", muDstMaker ); - } - - if (muDstMaker){ - StFwdQAMaker *fwdQA = new StFwdQAMaker(); - fwdQA->SetDebug(2); - TString fwdqaname(gSystem->BaseName(inFile)); - fwdqaname.ReplaceAll(".fzd", ".FwdTree.root"); - fwdQA->setTreeFilename(fwdqaname); - chain->AddAfter("MuDst", fwdQA); - } - - // The PicoDst - gSystem->Load("libStPicoEvent"); - gSystem->Load("libStPicoDstMaker"); - StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); - cout << "picoMk = " << picoMk << endl; - picoMk->setVtxMode(StPicoDstMaker::Default); - - -chain_loop: - chain->Init(); - - //_____________________________________________________________________________ - // - // MAIN EVENT LOOP - //_____________________________________________________________________________ - for (int i = 0; i < n; i++) { - - cout << "--------->START EVENT: " << i << endl; - - chain->Clear(); - if (kStOK != chain->Make()) - break; - - - // StMuDst * mds = muDstMaker->muDst(); - // StMuFwdTrackCollection * ftc = mds->muFwdTrackCollection(); - // cout << "Number of StMuFwdTracks: " << ftc->numberOfFwdTracks() << endl; - // for ( size_t iTrack = 0; iTrack < ftc->numberOfFwdTracks(); iTrack++ ){ - // StMuFwdTrack * muFwdTrack = ftc->getFwdTrack( iTrack ); - // cout << "muFwdTrack->mPt = " << muFwdTrack->momentum().Pt() << endl; - - // } - cout << "<---------- END EVENT" << endl; - } // event loop -} diff --git a/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C b/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C deleted file mode 100755 index ac8339cb399..00000000000 --- a/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C +++ /dev/null @@ -1,28 +0,0 @@ -//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? -#include "gen.C" -#include "TString.h" - -void single_particle_gun( Int_t nevents=5000, Int_t rngSeed=541522, - TString particle="mu-", Int_t nParticles=1, - Float_t _minPt=0.1, Float_t _maxPt=1.0, - Float_t _minEta=2.5, Float_t _maxEta=4.0, - Float_t _minPhi=0.0, Float_t _maxPhi=2.0*TMath::Pi() - ) -{ - nameParticle = particle; - numParticles = nParticles; - minPt = _minPt; - maxPt = _maxPt; - minEta = _minEta; - maxEta = _maxEta; - minPhi = _minPhi; - maxPhi = _maxPhi; - - TString safeName = particle; - safeName.ReplaceAll("+", "plus"); - safeName.ReplaceAll("-", "minus"); - fzdFilename = TString::Format("single_particle_gun_%s_%dEvents_%dPerEvent_Pt_%0.2fto%0.2f_Eta_%0.2fto%0.2f_Phi_%0.2fto%0.2f.fzd", safeName.Data(), nevents, numParticles, minPt, maxPt, minEta, maxEta, minPhi, maxPhi); - primaryName = TString::Format("single_particle_gun_%s_%dEvents_%dPerEvent_Pt_%0.2fto%0.2f_Eta_%0.2fto%0.2f_Phi_%0.2fto%0.2f.root", safeName.Data(), nevents, numParticles, minPt, maxPt, minEta, maxEta, minPhi, maxPhi); - cout << "Writing output to: " << fzdFilename << endl; - gen( nevents, rngSeed ); -} diff --git a/StRoot/StFwdTrackMaker/macro/viz.C b/StRoot/StFwdTrackMaker/macro/viz.C old mode 100755 new mode 100644 index db0d6e33f60..2768834e087 --- a/StRoot/StFwdTrackMaker/macro/viz.C +++ b/StRoot/StFwdTrackMaker/macro/viz.C @@ -1,9 +1,9 @@ -//usr/bin/env root -l -b -q $0'('$1')'; exit $? #include "TFile.h" #include "TH1F.h" #include "TH2F.h" #include "TTree.h" + TFile * fData; TTree * fwd; TH2 * hFrame; @@ -247,7 +247,7 @@ void viz_points(const char* name, const char* cmd, int color, int eventIndex, Pr //add function for seed finding-AGE void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType projType = kRZSigned){ - fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); + fwd->Draw( "reco.id", "", "goff", 1, eventIndex ); int nTrks = fwd->GetSelectedRows(); TLine line; @@ -256,7 +256,7 @@ void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType TLine proj; for (int i = 0; i < nTrks; i++){ //loop over number of tracks - fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); + fwd->Draw( TString::Format("reco[%d].projs.mXYZ.fX:reco[%d].projs.mXYZ.fY:reco[%d].projs.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); auto nHits = fwd->GetSelectedRows(); auto projX = fwd->GetV1(); auto projY = fwd->GetV2(); @@ -290,35 +290,7 @@ void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType line.SetLineColor(1); }*/ - -void viz_tracks(int nTrk, int eventIndex, ProjectionType projType, bool seeds = false, int iTrack = -1, bool filter = false){ - TLine ll; - ll.SetLineWidth(lineScale); - - // ll.DrawLine( 150, 10, 250, 20 ); - // Tracks - int NumTracksFound = 0; - for ( int i = 0; i < nTrk; i++ ){ - if ( iTrack >= 0 && i != iTrack ) continue; - - // fwd->Draw( TString::Format("reco[%d].projs.mXYZ.fX:reco[%d].projs.mXYZ.fY:reco[%d].projs.mXYZ.fZ", i, i, i), TString::Format("reco[%d].status>=1 && fabs(reco[%d].mChi2) > 0.5", i, i), "goff", 1, eventIndex ); - fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ:reco[%d].mChi2:reco[%d].mDidFitConverge:reco[%d].mCharge", i, i, i, i, i, i), "", "goff", 1, eventIndex ); - // fwd->Draw( TString::Format("0:5:reco[%d].projs.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); - auto trkX = fwd->GetV1(); - auto trkY = fwd->GetV2(); - auto trkZ = fwd->GetV3(); - auto trkChi2 = fwd->GetV4(); - auto trkConv = fwd->GetVal(4); - auto trkQ = fwd->GetVal(5); - - TText text; - text.SetTextFont(43); - text.SetTextSize(36); - if (iTrack >= 0){ - text.DrawTextNDC( 0.05, 0.7, TString::Format( "chi2=%f", trkChi2[0] ) ); - text.DrawTextNDC( 0.05, 0.65, TString::Format( "converge=%d", trkConv[0] ) ); - }else { - // if ( trkChi2[0] > 100 ) continue; + line.DrawLine(x0, y0, x1, y1); } } @@ -328,7 +300,7 @@ void viz_tracks(int nTrk, int eventIndex, ProjectionType projType, bool seeds = void viz_proj( int eventIndex, ProjectionType projType = kRZSigned, bool markers = false ){ //get number of tracks - fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex); //check if this is correct data to use to get nTrks + fwd->Draw( "reco.id", "", "goff", 1, eventIndex); //check if this is correct data to use to get nTrks int nTrks = fwd->GetSelectedRows(); //create line for track @@ -379,45 +351,26 @@ void viz_proj( int eventIndex, ProjectionType projType = kRZSigned, bool markers } } } - - if (seeds == false) return; - - for ( int i = 0; i < nTrk; i++ ){ - if ( iTrack >= 0 && i != iTrack ) continue; - - fwd->Draw( TString::Format("reco[%d].seeds.pos.fX:reco[%d].seeds.pos.fY:reco[%d].seeds.pos.fZ", i, i, i), TString::Format("reco[%d].mDidFitConverge!=0", i), "goff", 1, eventIndex ); - auto seedX = fwd->GetV1(); - auto seedY = fwd->GetV2(); - auto seedZ = fwd->GetV3(); - - // printf( "Found %d seeds for track %d\n", fwd->GetSelectedRows(), i ); - // int slc = TColor::GetColorPalette(i*100 % 255); - ll.SetLineColor(kGreen); - - for ( int j = 0; j < fwd->GetSelectedRows()-1; j++ ){ - - float seedX1 = xx( seedX[j], seedY[j], seedZ[j], projType ); - float seedY1 = yy( seedX[j], seedY[j], seedZ[j], projType ); - - // printf( "seed(x=%f, y=%f, z=%)->(xx=%f, yy=%f)\n", seedX[j], seedY[j], seedZ[j], seedX1, seedY1 ); - - float seedX2 = xx( seedX[j+1], seedY[j+1], seedZ[j+1], projType ); - float seedY2 = yy( seedX[j+1], seedY[j+1], seedZ[j+1], projType ); - - // printf( "(%f, %f) -> (%f, %f)\n", seedX1, seedY1, seedX2, seedY2 ); - ll.DrawLine( seedX1, seedY1, seedX2, seedY2 ); - - TMarker *mk1 = new TMarker( seedX1, seedY1, 20 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColor(kBlue); - mk1->Draw("same"); - - TMarker *mk2 = new TMarker( seedX2, seedY2, 20 ); - mk2->SetMarkerSize( 2.5 ); - mk2->SetMarkerColor(kBlue); - mk2->Draw("same"); - } // end loop j - } // end loop i + if (markers){ + //add marker to the legend + TText *t = new TText(.5,.5,"Hello World !"); + t->SetTextColor(kBlack); + t->SetTextFont(43); + t->SetTextSize(20); + //make this more functional? + if ( projType == kRZSigned ){ + LegendY = 5; + } else if (projType == kXY ){ + LegendY = -15; + } + TMarker *mk1 = new TMarker( LegendX, LegendY, 23 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColor( 2 ); + mk1->Draw("same"); + t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "Projected Hits ") ); + } + +} //end of fn //add function to compare lines @@ -442,7 +395,7 @@ void viz_stats( int eventIndex ){ fwd->Draw( "fcsX:fcsY:fcsZ", "", "goff", 1, eventIndex ); int numEpd = fwd->GetSelectedRows();*/ - fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); + fwd->Draw( "reco.id", "", "goff", 1, eventIndex ); int numTracks = fwd->GetSelectedRows(); fwd->Draw( "fst.pos.fX:fst.pos.fY:fst.pos.fZ", "", "goff", 1, eventIndex ); int numFst = fwd->GetSelectedRows(); @@ -469,21 +422,12 @@ void viz_stats( int eventIndex ){ text.DrawTextNDC( 0.05, statTextY, TString::Format("WCal Clusters : %d", numWcal) ); n(); text.DrawTextNDC( 0.05, statTextY, TString::Format("HCal Clusters : %d", numHcal) ); n(); - fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, eventIndex ); - text.DrawTextNDC( 0.05, statTextY, TString::Format("#Tracks : %d", fwd->GetSelectedRows()) ); n(); - - fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100", "goff", 1, eventIndex ); - text.DrawTextNDC( 0.05, statTextY, TString::Format("#Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); - - fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100 && reco.mCharge==1", "goff", 1, eventIndex ); - text.DrawTextNDC( 0.05, statTextY, TString::Format("#Pos Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); - fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100 && reco.mCharge==-1", "goff", 1, eventIndex ); - text.DrawTextNDC( 0.05, statTextY, TString::Format("#Neg Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); + //print reco statistics + /*fwd->Draw( "reco.reco.projs.mXYZ:fX:reco.reco.projs.mXYZ:fY:reco.reco.projs.mXYZ:fZ", "", "goff", 1, eventIndex ); + int numReco = fwd->GetSelectedRows(); + statTextY = 0.92; + text.DrawTextNDC( 0.35, statTextY, TString::Format("Reco Hits : %d", numReco) ); n();*/ - // fwd->Draw( "seeds.trackId", "", "goff", 1, eventIndex ); - // fwd->Draw( "nSeedTracks", "", "goff", 1, eventIndex ); - // mTotalSeeds = fwd->GetV1()[0]; - text.DrawTextNDC( 0.05, statTextY, TString::Format("#Seeds : %d", mTotalSeeds ) ); n(); } @@ -508,17 +452,15 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ printf( "Visualizing Event %d \n", eventIndex ); - fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, eventIndex ); - int nTrk = fwd->GetSelectedRows(); - printf( "Event has %lld Tracks \n", nTrk ); + fwd->Draw( "reco.id", "", "", 1, eventIndex ); + int nTrk = fwd->GetSelectedRows(); //number of reco tracks + printf( "Event has %d Tracks \n", nTrk ); //changed from %lld to %d to eliminate an error that occurred-AGE hFrame->Draw("colz"); - viz_points( "FTT", "fttPoints.mXYZ.fX:fttPoints.mXYZ.fY:fttPoints.mXYZ.fZ", kRed, eventIndex, projType ); - // viz_points( "FTC", "fttClusters.pos.fX:fttClusters.pos.fY:-fttClusters.pos.fZ", kGreen, eventIndex, projType, "fttClusters.mNStrips>2" ); - viz_points( "FST", "fstHits.mXYZ.fX:fstHits.mXYZ.fY:fstHits.mXYZ.fZ", kRed, eventIndex, projType ); - viz_points( "FCS", "wcalClusters.mXYZ.fX:wcalClusters.mXYZ.Y():wcalClusters.mXYZ.Z():wcalClusters.mClu.mEnergy", kGray, eventIndex, projType ); + //add detector locations + if (projType == kRZSigned){ TLine *fst1 = new TLine(151.75, -28.3, 151.75, 28.3); fst1->SetLineWidth(2); @@ -533,9 +475,22 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ fst3->SetLineColor(12); fst3->Draw("same"); - - viz_tracks(nTrk, eventIndex, projType, false); - //viz_seeds(nTrk, eventIndex, projType); + TLine *ftt1 = new TLine(281, -60, 281, 60); + ftt1->SetLineWidth(2); + ftt1->SetLineColor(12); + ftt1->Draw("same"); + TLine *ftt2 = new TLine(304, -60, 304, 60); + ftt2->SetLineWidth(2); + ftt2->SetLineColor(12); + ftt2->Draw("same"); + TLine *ftt3 = new TLine(325, -60, 325, 60); + ftt3->SetLineWidth(2); + ftt3->SetLineColor(12); + ftt3->Draw("same"); + TLine *ftt4 = new TLine(348, -60, 348, 60); + ftt4->SetLineWidth(2); + ftt4->SetLineColor(12); + ftt4->Draw("same"); TLine *epd = new TLine(375, -130, 375, 130); epd->SetLineWidth(2); @@ -555,15 +510,15 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ //viz_points( "FST", "fstX:fstY:fstZ", kGray, eventIndex, projType/*, true*/ ); //viz_points( "EPD", "epdX:epdY:epdZ:epdE", kBlue, eventIndex, projType/*, true*/ ); //epd hits (only in fwdtree2)-AGE //viz_points( "FCS", "fcsX:fcsY:fcsZ:fcsE", kGreen, eventIndex, projType/*, true*/ ); - viz_points( "FST", "fst.mXYZ.fX:fst.mXYZ.fY:fst.mXYZ.fZ", kGray, eventIndex, projType, true ); - viz_points( "FTT", "ftt.mXYZ.fX:ftt.mXYZ.fY:ftt.mXYZ.fZ", kRed, eventIndex, projType ); - // viz_points( "FTT Clusters", "fttClusters.pos.fX:fttClusters.pos.fY:fttClusters.pos.fZ", kRed, eventIndex, projType ); - // viz_points( "WCal Hits", "wcalHits.starXYZ.fX:wcalHits.starXYZ.fY:wcalHits.starXYZ.fZ+705:100*wcalHits.energy", kBlue, eventIndex, projType ); - // viz_points( "HCal Hits", "hcalHits.starXYZ.fX:hcalHits.starXYZ.fY:hcalHits.starXYZ.fZ+785:100*wcalClusters.mEnergy", kTeal, eventIndex, projType/*, true*/ ); - // viz_points( "WCal Clusters", "wcalClusters.pos.fX:wcalClusters.pos.fY:wcalClusters.pos.fZ+705:100*wcalClusters.mEnergy", kViolet, eventIndex, projType/*, true*/ ); - // viz_points( "HCal Clusters", "hcalClusters.pos.fX:hcalClusters.pos.fY:hcalClusters.pos.fZ+785:100*wcalClusters.mEnergy", kGreen, eventIndex, projType/*, true*/ ); //add fcs hits-AGE - - // viz_seed( "Se-=[eds", "seeds.pos.fX:seeds.pos.fY:seeds.pos.fZ", eventIndex, projType ); + viz_points( "FST", "fst.pos.fX:fst.pos.fY:fst.pos.fZ", kGray, eventIndex, projType, true ); + viz_points( "FTT", "ftt.pos.fX:ftt.pos.fY:ftt.pos.fZ", kRed, eventIndex, projType ); + viz_points( "FTT Clusters", "fttClusters.pos.fX:fttClusters.pos.fY:fttClusters.pos.fZ", kRed, eventIndex, projType ); + viz_points( "WCal Hits", "wcalHits.starXYZ.fX:wcalHits.starXYZ.fY:wcalHits.starXYZ.fZ+705:100*wcalHits.energy", kBlue, eventIndex, projType ); + viz_points( "HCal Hits", "hcalHits.starXYZ.fX:hcalHits.starXYZ.fY:hcalHits.starXYZ.fZ+785:100*wcalClusters.mEnergy", kTeal, eventIndex, projType/*, true*/ ); + viz_points( "WCal Clusters", "wcalClusters.pos.fX:wcalClusters.pos.fY:wcalClusters.pos.fZ+705:100*wcalClusters.mEnergy", kViolet, eventIndex, projType/*, true*/ ); + viz_points( "HCal Clusters", "hcalClusters.pos.fX:hcalClusters.pos.fY:hcalClusters.pos.fZ+785:100*wcalClusters.mEnergy", kGreen, eventIndex, projType/*, true*/ ); //add fcs hits-AGE + + viz_seed( "Seeds", "seeds.pos.fX:seeds.pos.fY:seeds.pos.fZ", eventIndex, projType ); //viz_proj( eventIndex, projType, false); //viz_points( "Proj", "reco.reco.projs.mXYZ.fX:reco.reco.projs.mXYZ.fY:reco.reco.projs.mXYZ.fZ", kRed, eventIndex, projType); return nTrk; @@ -571,10 +526,9 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ //change to name of file being used-AGE -void viz( int maxEvents = 10, TString fn = "fwdtree.root", int view = kXY) { - -void viz( int mode = 0, int maxEvents = 10, TString fn = "fwdtree.root") { +void viz( TString fn = "fwdtree5.root", int view = kXY) { + ProjectionType pjt = (ProjectionType)view; fData = new TFile( fn ); fwd = (TTree*)fData->Get( "fwd" ); @@ -607,7 +561,6 @@ void viz( int mode = 0, int maxEvents = 10, TString fn = "fwdtree.root") { // gPad->SetMargin(0.1, 0.05, 0.15, 0.05); int nEvents = fwd->GetEntries(); - if (nEvents > maxEvents) nEvents = maxEvents; // nEvents = 1; for ( int iEvent = 0; iEvent < nEvents; iEvent ++ ){ @@ -628,7 +581,7 @@ void viz( int mode = 0, int maxEvents = 10, TString fn = "fwdtree.root") { padStat->cd(); padStat->Clear(); - // viz_stats( iEvent ); //changed to provide number of tracks as well-AGE + viz_stats( iEvent ); //changed to provide number of tracks as well-AGE padStat->Update(); gCan->Update(); gCan->Print( TString::Format( "out_event%d.pdf", iEvent ) ); @@ -642,37 +595,4 @@ void viz( int mode = 0, int maxEvents = 10, TString fn = "fwdtree.root") { hFrame->Reset(); } - if ( mode != 1 ) return; - // visualize the event one track at a time - for ( int inEvent = 0; inEvent < nEvents; inEvent++ ){ - fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, inEvent ); - int nTrk = fwd->GetSelectedRows(); - printf( "Event %d has %lld Tracks \n", inEvent, nTrk ); - - for ( int iTrack = 0; iTrack < nTrk; iTrack ++ ){ - - printf( "Track: %d\n", iTrack ); - - padRZ->cd(); - // int nTrk = viz_event( iEvent, kRZSigned ); - viz_event( inEvent, kRZSigned, true ); - viz_tracks(nTrk, inEvent, kRZSigned, true, iTrack); - padXY->cd(); - viz_event( inEvent, kXY, true ); - viz_tracks(nTrk, inEvent, kXY, true, iTrack); - if (nTrk > -1){ - padRZ->Update(); - padXY->Update(); - - padStat->cd(); - padStat->Clear(); - // viz_stats( iEvent ); - padStat->Update(); - gCan->Update(); - gCan->Print( TString::Format( "out_event%d_track%d.pdf", inEvent, iTrack ) ); - } - hFrame->Reset(); - } - } - -} +} \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/viz2.C b/StRoot/StFwdTrackMaker/macro/viz2.C deleted file mode 100755 index be2db879e82..00000000000 --- a/StRoot/StFwdTrackMaker/macro/viz2.C +++ /dev/null @@ -1,600 +0,0 @@ -//usr/bin/env root -l -b -q $0'('$1')'; exit $? -#include "TFile.h" -#include "TH1F.h" -#include "TH2F.h" -#include "TTree.h" - - -TFile * fData; -TTree * fwd; -TH2 * hFrame; -TCanvas *gCan; -TPad *padRZ, *padXY, *padStat; - -float LegendX, LegendY; -float lineScale = 1.5; - -enum ProjectionType { kXY, kRZ, kRZSigned, kXZ, kYZ }; - -float xx( float x, float y, float z, ProjectionType proj = kRZ ){ - - if ( proj == kRZ || proj == kRZSigned){ - return z;//(TMath::ATan2( y, x ) + 2*3.1415926 )/ (2*3.14159) * 360; - } else if ( proj == kXY ){ - return x; - } else if ( proj == kXZ ){ - return z; - } else if ( proj == kYZ ){ - return z; - } - - return x; -} - -float yy( float x, float y, float z, ProjectionType proj = kRZ ){ - - if ( proj == kRZ ){ - float r = sqrt( pow(x, 2) + pow(y, 2) ); - return r; - } else if ( proj == kXY ){ - return y; - } else if ( proj == kRZSigned ){ - float r = sqrt( pow(x, 2) + pow(y, 2) ); - if ( y == 0 ) return r; - r *= y / fabs(y); - return r; - } else if ( proj == kXZ ){ - return x; - } else if ( proj == kYZ ){ - return y; - } - - return y; -} - -void viz_points(const char* name, const char* cmd, int color, int eventIndex, ProjectionType projType, bool Legend = false ){ - - fwd->Draw( cmd, "", "goff", 1, eventIndex ); - int N = fwd->GetSelectedRows(); - printf( "%s : has %d results \n", cmd, N ); - printf( "Projection Mode : %d \n", projType ); - - auto cmdX = fwd->GetV1(); - auto cmdY = fwd->GetV2(); - auto cmdZ = fwd->GetV3(); - auto cmdE = fwd->GetV4(); - if ( cmdE != nullptr ){ - printf( "TOWERS\n" ); - } - float vizX; //change from array-AGE - float vizY; - - TText *t = new TText(.5,.5,"Hello World !"); - // t->SetTextAlign(22); - t->SetTextColor(kBlack); - t->SetTextFont(43); - t->SetTextSize(20); - - int zColorStep = 90; - int slc = color; - int zColors[50]; // fst1 fst2 fst3 ftt1 ftt2 ftt3 ftt4 epd ecal hcal - float zSizes[] = {2.5, 2.5, 2.0, 1.5, 1.5, 1.5, 1.5, 1.5, 2.5, 2.0, 1.5}; //first element is for hits that don't match any positions (only goes to ftt3--changing to allow all) - for ( int i = 0; i < 50; i++ ) - zColors[i] = TColor::GetColorPalette(i*zColorStep % 255 ); - - - bool lgZ = false; - float alpha = 0.6; - for ( int i = 0; i < N; i++ ){ - - vizX = xx( cmdX[i], cmdY[i], cmdZ[i], projType ); - vizY = yy( cmdX[i], cmdY[i], cmdZ[i], projType ); - printf( "\tpoint at (%f, %f, %f) -> (%f, %f)\n", cmdX[i], cmdY[i], cmdZ[i], vizX, vizY ); - - int zIndex = 0; - if ( fabs( cmdZ[i] - 151.75) < 2.5 ) zIndex = 1; - if ( fabs( cmdZ[i] - 165.25) < 2.5 ) zIndex = 2; - if ( fabs( cmdZ[i] - 178.75) < 2.5 ) zIndex = 3; - - //add locations of other detectors-AGE - //FTT--approximate locations - if ( fabs( cmdZ[i] - 281) < 2.5 ) zIndex = 4; - if ( fabs( cmdZ[i] - 304) < 2.5 ) zIndex = 5; - if ( fabs( cmdZ[i] - 325) < 2.5 ) zIndex = 6; - if ( fabs( cmdZ[i] - 348) < 2.5 ) zIndex = 7; - //EPD--approx. - if ( fabs( cmdZ[i] - 375) < 2.5 ) zIndex = 8; - //FCS--approx. - //if ( fabs( cmdZ[i] - 721) < 2.5 ) zIndex = 9; //wcal - //if ( fabs( cmdZ[i] - 804) < 2.5 ) zIndex = 10; //hcal - - TMarker *mk = new TMarker( vizX, vizY, 20 ); - - mk->SetMarkerSize( 2.5 ); - if (zIndex >= 1 && zIndex < 50){ //see if should be changed to zIndex < 9-AGE - slc = zColors[zIndex]; - } - mk->SetMarkerSize( zSizes[zIndex] ); - - - - - // mk->SetMarkerSize( (float)(zIndex) * 0.5 + 0.5 ); - - alpha = 0.6; - if ( zIndex != 8 && (cmdE != nullptr && projType == kRZSigned) ){ //FCS for RZ - //mk->SetMarkerStyle( 21 ); //sets marker to a square, change to use TBox instead-AGE - //mk->SetMarkerSize( 0.5 + 0.5 * cmdE[i] ); - mk->SetMarkerSize(0); - alpha = (cmdE[i] / 10.0); - if (alpha>=1) alpha = 1; - TBox *box = new TBox( vizX-0.05*cmdE[i], vizY-0.5, vizX, vizY+0.5 ); - box->SetFillColor(210); - if ( name == "WCal Clusters" || name == "HCal CLusters" ){ - box->SetFillColor(880); - mk->SetMarkerSize(1); - } - box->Draw("same"); - } - if ( name == "FTT Clusters" && projType == kXY ){ - mk->SetMarkerSize(0); - TLine XCluster; - XCluster.SetLineWidth(1); - XCluster.SetLineColor(9); //dark blue - TLine YCluster; - YCluster.SetLineWidth(1); - YCluster.SetLineColor(46); //dark red - float x0; - float x1; - float y0; - float y1; - if (vizX < 0){ - x0 = -50; - x1 = 0; - } else if(vizX >= 0){ - x0 = 0; - x1 = 50; - } - if (vizY < 0){ - y0 = -50; - y1 = 0; - } else if (vizY >= 0){ - y0 = 0; - y1 = 50; - } - - XCluster.DrawLine(vizX, y0, vizX, y1); - YCluster.DrawLine(x0, vizY, x1, vizY); - - } - - if ( cmdE != nullptr && (zIndex == 8 || projType != kRZSigned) ){ //EPD for RZ and EPD and FCS for XY - mk->SetMarkerStyle(21); - mk->SetMarkerSize( 0.005 * cmdE[i]); - } - - printf( "\tzIndex = %d -> color = %d \n", zIndex, slc ); - - mk->SetMarkerColorAlpha( slc, alpha ); - if ( zIndex >= 1 ){ - mk->SetMarkerColorAlpha( slc, alpha ); - lgZ = true; - } - - //change marker style etc. for projected points only-AGE - /*if( name == "Proj" ){ - mk->SetMarkerStyle(23); - mk->SetMarkerColor(2); - mk->SetMarkerSize(1.5); - }*/ - - mk->Draw("same"); - - } - - if ( lgZ ){ - /*for ( int i = 1; i < 4; i++){ - TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColorAlpha( zColors[i], 0.5 ); - mk1->Draw("same"); - t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s: %d", name, i ) ); - - LegendY -= 5; - }*/ - if (name == "FST"){ - for ( int i = 1; i < 4; i++ ){ - TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColorAlpha( zColors[i], 0.5 ); - mk1->Draw("same"); - t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s: %d", name, i ) ); - - LegendY -= 5; - } - } else if (name == "FTT"){ - for ( int i = 1; i < 5; i++ ){ - TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColorAlpha( zColors[i+3], 0.5 ); - mk1->Draw("same"); - t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s: %d", name, i ) ); - - LegendY -= 5; - } - } else if (name == "FCS"){ - for ( int i = 1; i < 3; i++ ){ - TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColorAlpha( zColors[i], 0.5 ); - mk1->Draw("same"); - t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s: %d", name, i ) ); - - LegendY -= 5; - } - } - - } else { - TMarker *mk1 = new TMarker( LegendX, LegendY, 20 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColor( color ); - mk1->Draw("same"); - t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "%s:", name ) ); - - LegendY -= 5; - } -} - -//add function for seed finding-AGE -void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType projType = kRZSigned){ - - fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); - int nTrks = fwd->GetSelectedRows(); - - TLine line; - line.SetLineWidth(2); - line.SetLineColor(1); - TLine proj; - for (int i = 0; i < nTrks; i++){ //loop over number of tracks - - fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); - auto nHits = fwd->GetSelectedRows(); - auto projX = fwd->GetV1(); - auto projY = fwd->GetV2(); - auto projZ = fwd->GetV3(); - /*std::vector projX; - std::vector projY; - std::vector projZ; - - for (int hit = 0; hit < nHits; ++hit) { - projX.push_back(fwd->GetV1()[hit]); - projY.push_back(fwd->GetV2()[hit]); - projZ.push_back(fwd->GetV3()[hit]); - }*/ - - //select only the seeds that have same track id as track number - fwd->Draw( cmd, TString::Format("seeds.mTrackId == %d", i), "goff", 1, eventIndex ); - //fwd->Draw( TString::Format("seeds[%d].mXYZ.fX:seeds[%d].mXYZ.fY:seeds[%d].mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); - int numSeeds = fwd->GetSelectedRows(); - auto newX = fwd->GetV1(); - auto newY = fwd->GetV2(); - auto newZ = fwd->GetV3(); - - for ( int j = 0; j < numSeeds - 1; j++){ - - float x0 = xx( newX[j], newY[j], newZ[j], projType ); - float y0 = yy( newX[j], newY[j], newZ[j], projType ); - float x1 = xx( newX[j+1], newY[j+1], newZ[j+1], projType ); - float y1 = yy( newX[j+1], newY[j+1], newZ[j+1], projType ); - - /*if ( fabs(x0 - projX[j+1]) <= 1 ){ - line.SetLineColor(1); - }*/ - - line.DrawLine(x0, y0, x1, y1); - } - - } -} - -//add function for track projection -void viz_proj( int eventIndex, ProjectionType projType = kRZSigned, bool markers = false ){ - - //get number of tracks - fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex); //check if this is correct data to use to get nTrks - int nTrks = fwd->GetSelectedRows(); - - //create line for track - TLine trkproj; - trkproj.SetLineWidth(1.5); - trkproj.SetLineColor(24); //light green - - //loop over each track in the event - for ( int i = 0; i < nTrks; i++ ){ - - //get hits in i'th track - fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); - auto nHits = fwd->GetSelectedRows(); - auto projX = fwd->GetV1(); - auto projY = fwd->GetV2(); - auto projZ = fwd->GetV3(); - - - //loop over hits in each track - for ( int j = 0; j < nHits - 1; j++ ){ - - //assign the x and y positions of the track projection - float x0 = xx( projX[j], projY[j], projZ[j], projType ); - float y0 = yy( projX[j], projY[j], projZ[j], projType ); - float x1 = xx( projX[j+1], projY[j+1], projZ[j+1], projType ); - float y1 = yy( projX[j+1], projY[j+1], projZ[j+1], projType ); - - /*trkproj.SetLineColor(i+2); - if (i == 0 || i == 10 ){ - trkproj.SetLineColor(1); - }*/ - trkproj.DrawLine(x0, y0, x1, y1); - } - - //add markers - if (markers){ - for ( int j = 0; j < nHits; j++ ){ - - float x = xx( projX[j], projY[j], projZ[j], projType ); - float y = yy( projX[j], projY[j], projZ[j], projType ); - - TMarker *mk = new TMarker( x, y, 20); - mk->SetMarkerStyle(23); - mk->SetMarkerColor(2); - mk->SetMarkerSize(1.5); - - mk->Draw("same"); - } - } - } - if (markers){ - //add marker to the legend - TText *t = new TText(.5,.5,"Hello World !"); - t->SetTextColor(kBlack); - t->SetTextFont(43); - t->SetTextSize(20); - //make this more functional? - if ( projType == kRZSigned ){ - LegendY = 5; - } else if (projType == kXY ){ - LegendY = -15; - } - TMarker *mk1 = new TMarker( LegendX, LegendY, 23 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColor( 2 ); - mk1->Draw("same"); - t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "Projected Hits ") ); - } - -} //end of fn - - -//add function to compare lines -//float comp_lines() - - -float statTextY = 0.97; -void n() { statTextY -= 0.05; } -void viz_stats( int eventIndex ){ - statTextY = 0.97; - TText text; - text.SetTextFont(43); - text.SetTextSize(36); - - - /*fwd->Draw( "fstX:fstY:fstZ", "", "goff", 1, eventIndex ); - int numEpd = fwd->GetSelectedRows(); - fwd->Draw( "fttX:fttY:fttZ", "", "goff", 1, eventIndex ); - int numEpd = fwd->GetSelectedRows(); - fwd->Draw( "epdX:epdY:epdZ", "", "goff", 1, eventIndex ); - int numEpd = fwd->GetSelectedRows(); - fwd->Draw( "fcsX:fcsY:fcsZ", "", "goff", 1, eventIndex ); - int numEpd = fwd->GetSelectedRows();*/ - - fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); - int numTracks = fwd->GetSelectedRows(); - fwd->Draw( "fstHits.mXYZ.fX:fstHits.mXYZ.fY:fstHits.mXYZ.fZ", "", "goff", 1, eventIndex ); - int numFst = fwd->GetSelectedRows(); - fwd->Draw( "fttPoints.mXYZ.fX:fttPoints.mXYZ.fY:fttPoints.mXYZ.fZ", "", "goff", 1, eventIndex ); - int numFtt = fwd->GetSelectedRows(); - //fwd->Draw( "EPD hits", "", "goff", 1, eventIndex ); - //int numEpd = fwd->GetSelectedRows(); - fwd->Draw( "wcalHits.mXYZ.fX:wcalHits.mXYZ.fY:wcalHits.mXYZ.fZ", "", "goff", 1, eventIndex ); - int numWcalHits = fwd->GetSelectedRows(); - fwd->Draw( "hcalHits.mXYZ.fX:hcalHits.mXYZ.fY:hcalHits.mXYZ.fZ", "", "goff", 1, eventIndex ); - int numHcalHits = fwd->GetSelectedRows(); - fwd->Draw( "wcalClusters.mXYZ.fX:wcalClusters.mXYZ.fY:wcalClusters.mXYZ.fZ", "", "goff", 1, eventIndex ); - int numWcal = fwd->GetSelectedRows(); - fwd->Draw( "hcalClusters.mXYZ.fX:hcalClusters.mXYZ.fY:hcalClusters.mXYZ.fZ", "", "goff", 1, eventIndex ); - int numHcal = fwd->GetSelectedRows(); - - text.DrawTextNDC( 0.05, statTextY, TString::Format("Event : %d", eventIndex) ); n(); - text.DrawTextNDC( 0.05, statTextY, TString::Format("Tracks : %d", numTracks) ); n(); - text.DrawTextNDC( 0.05, statTextY, TString::Format("FST Hits : %d", numFst) ); n(); - text.DrawTextNDC( 0.05, statTextY, TString::Format("FTT Hits : %d", numFtt) ); n(); - //text.DrawTextNDC( 0.05, statTextY, TString::Format("EPD Hits : %d", numEpd) ); n(); - //text.DrawTextNDC( 0.05, statTextY, TString::Format("WCal Hits : %d", numWcalHits) ); n(); - //text.DrawTextNDC( 0.05, statTextY, TString::Format("HCal Hits : %d", numHcalHits) ); n(); - text.DrawTextNDC( 0.05, statTextY, TString::Format("WCal Clusters : %d", numWcal) ); n(); - text.DrawTextNDC( 0.05, statTextY, TString::Format("HCal Clusters : %d", numHcal) ); n(); - - //print reco statistics - /*fwd->Draw( "reco.mProjections.mXYZ:fX:reco.mProjections.mXYZ:fY:reco.mProjections.mXYZ:fZ", "", "goff", 1, eventIndex ); - int numReco = fwd->GetSelectedRows(); - statTextY = 0.92; - text.DrawTextNDC( 0.35, statTextY, TString::Format("Reco Hits : %d", numReco) ); n();*/ - -} - - -int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ - - if ( projType == kRZSigned || projType == kXZ || projType == kYZ ){ - hFrame = new TH2F( "hFrame", ";z;R", 520, -30, 900, 260, -130, 130 ); - hFrame->SetTitle( "Event Visualization (RZ Signed)" ); - LegendX = 10; - LegendY = 60; - } else if ( projType == kRZ ){ - hFrame = new TH2F( "hFrame", ";z;R", 500, 0, 900, 60, 0, 60 ); - hFrame->SetTitle( "Event Visualization (RZ Signed)" ); - LegendX = 10; - LegendY = 60; - } else if ( projType == kXY ){ - hFrame = new TH2F( "hFrame", ";x;y", 5, -50, 50, 5, -50, 50 ); - hFrame->SetTitle( "Event Visualization (XY)" ); - LegendX = -40; - LegendY = 40; - } - - printf( "Visualizing Event %d \n", eventIndex ); - - fwd->Draw( "reco.mChi2", "", "", 1, eventIndex ); - int nTrk = fwd->GetSelectedRows(); //number of reco tracks - printf( "Event has %d Tracks \n", nTrk ); //changed from %lld to %d to eliminate an error that occurred-AGE - - - hFrame->Draw("colz"); - - //add detector locations - if (projType == kRZSigned){ - - TLine *fst1 = new TLine(151.75, -28.3, 151.75, 28.3); - fst1->SetLineWidth(2); - fst1->SetLineColor(12); - fst1->Draw("same"); - TLine *fst2 = new TLine(165.25, -28.3, 165.25, 28.3); - fst2->SetLineWidth(2); - fst2->SetLineColor(12); - fst2->Draw("same"); - TLine *fst3 = new TLine(178.75, -28.3, 178.75, 28.3); - fst3->SetLineWidth(2); - fst3->SetLineColor(12); - fst3->Draw("same"); - - TLine *ftt1 = new TLine(281, -60, 281, 60); - ftt1->SetLineWidth(2); - ftt1->SetLineColor(12); - ftt1->Draw("same"); - TLine *ftt2 = new TLine(304, -60, 304, 60); - ftt2->SetLineWidth(2); - ftt2->SetLineColor(12); - ftt2->Draw("same"); - TLine *ftt3 = new TLine(325, -60, 325, 60); - ftt3->SetLineWidth(2); - ftt3->SetLineColor(12); - ftt3->Draw("same"); - TLine *ftt4 = new TLine(348, -60, 348, 60); - ftt4->SetLineWidth(2); - ftt4->SetLineColor(12); - ftt4->Draw("same"); - - TLine *epd = new TLine(375, -130, 375, 130); - epd->SetLineWidth(2); - epd->SetLineColor(12); - epd->Draw("same"); - - //add tboxes for fcs - TBox *wcal = new TBox( 720, -120, 735, 120 ); - wcal->SetFillColorAlpha(4, 0.2); - wcal->Draw("same"); - TBox *hcal = new TBox( 800, -120, 815, 120 ); - hcal->SetFillColorAlpha(2, 0.2); - hcal->Draw("same"); - - } - - //viz_points( "FST", "fstX:fstY:fstZ", kGray, eventIndex, projType/*, true*/ ); - //viz_points( "EPD", "epdX:epdY:epdZ:epdE", kBlue, eventIndex, projType/*, true*/ ); //epd hits (only in fwdtree2)-AGE - //viz_points( "FCS", "fcsX:fcsY:fcsZ:fcsE", kGreen, eventIndex, projType/*, true*/ ); - viz_points( "FST", "fstHits.mXYZ.fX:fstHits.mXYZ.fY:fstHits.mXYZ.fZ", kGray, eventIndex, projType, true ); - viz_points( "FTT", "fttPoints.mXYZ.fX:fttPoints.mXYZ.fY:fttPoints.mXYZ.fZ", kRed, eventIndex, projType ); - // viz_points( "FTT Clusters", "fttClusters.mXYZ.fX:fttClusters.mXYZ.fY:fttClusters.mXYZ.fZ", kRed, eventIndex, projType ); - viz_points( "WCal Hits", "wcalHits.mXYZ.fX:wcalHits.mXYZ.fY:wcalHits.mXYZ.fZ+705:100*wcalHits.mHit.mEnergy", kBlue, eventIndex, projType ); - viz_points( "HCal Hits", "hcalHits.mXYZ.fX:hcalHits.mXYZ.fY:hcalHits.mXYZ.fZ+785:100*wcalClusters.mClu.mEnergy", kTeal, eventIndex, projType/*, true*/ ); - viz_points( "WCal Clusters", "wcalClusters.mXYZ.fX:wcalClusters.mXYZ.fY:wcalClusters.mXYZ.fZ:100*wcalClusters.mClu.mEnergy", kViolet, eventIndex, projType/*, true*/ ); - viz_points( "HCal Clusters", "hcalClusters.mXYZ.fX:hcalClusters.mXYZ.fY:hcalClusters.mXYZ.fZ:100*wcalClusters.mClu.mEnergy", kGreen, eventIndex, projType/*, true*/ ); //add fcs hits-AGE - - viz_seed( "Seeds", "seeds.mXYZ.fX:seeds.mXYZ.fY:seeds.mXYZ.fZ", eventIndex, projType ); - viz_proj( eventIndex, projType, false); - viz_points( "Proj", "reco.mProjections.mXYZ.fX:reco.mProjections.mXYZ.fY:reco.mProjections.mXYZ.fZ", kRed, eventIndex, projType); - return nTrk; -} - - -//change to name of file being used-AGE -void viz2( TString fn = "fwdtree.root", int view = kXY) { - - ProjectionType pjt = (ProjectionType)view; - fData = new TFile( fn ); - fwd = (TTree*)fData->Get( "fwd" ); - - gStyle->SetOptStat(0); - - float canWidth = 19 * 100; - float canHeight = 16 * 100; - gCan = new TCanvas( "g", "", canWidth, canHeight ); - gCan->SetMargin( 0, 0, 0, 0); - gCan->cd(); - gCan->Draw(); - - padRZ = new TPad( "padRZ", "", 0.0, 0.5, 0.95, 0.99 ); - padRZ->SetMargin( .05,.01,.05,.01 ); - padRZ->Draw("same"); - padRZ->cd(); - - gCan->cd(); - padXY = new TPad( "padXY", "", 0.0, 0.0, 0.5, 0.5 ); - padXY->SetMargin( .1,.02,.05,.01 ); - padXY->Draw("same"); - padXY->cd(); - - gCan->cd(); - padStat = new TPad( "padStat", "", 0.5, 0.0, 1.0, 0.5 ); - padStat->SetMargin( .1,.02,.05,.01 ); - padStat->Draw("same"); - padStat->cd(); - - // gPad->SetMargin(0.1, 0.05, 0.15, 0.05); - - int nEvents = fwd->GetEntries(); - // nEvents = 1; - // nEvents = 10; - for ( int iEvent = 0; iEvent < nEvents; iEvent ++ ){ - - printf( "Event: %d\n", iEvent ); - padRZ->cd(); - - //TBox *wcal = new TBox( 720, -60, 735, 60 ); - //wcal->SetFillColor(4); - //wcal->Draw(""); - int nTrk = viz_event( iEvent, kRZSigned ); - - - padXY->cd(); - viz_event( iEvent, kXY ); - if (nTrk > -1){ - padRZ->Update(); - padXY->Update(); - - padStat->cd(); - padStat->Clear(); - viz_stats( iEvent ); //changed to provide number of tracks as well-AGE - padStat->Update(); - gCan->Update(); - gCan->Print( TString::Format( "out_event%d.pdf", iEvent ) ); - } - - - // cin.get(); - // if (viz_event( iEvent ) > 0 ) - // break; - - hFrame->Reset(); - } - -} diff --git a/StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx b/StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx index 0f66f8c0c68..031a156db9e 100644 --- a/StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx +++ b/StRoot/StMuDSTMaker/COMMON/StMuDstMaker.cxx @@ -850,17 +850,17 @@ void StMuDstMaker::setBranchAddresses(TChain* chain) { mStMuDst->set(this); } - // if (!mFmsCollection) { - // mFmsCollection=new StMuFmsCollection(); - // connectFmsCollection(); - // mStMuDst->set(this); - // } - - // if (!mRHICfCollection) { - // mRHICfCollection=new StMuRHICfCollection(); - // connectRHICfCollection(); - // mStMuDst->set(this); - // } + if (!mFmsCollection) { + mFmsCollection=new StMuFmsCollection(); + connectFmsCollection(); + mStMuDst->set(this); + } + + if (!mRHICfCollection) { + mRHICfCollection=new StMuRHICfCollection(); + connectRHICfCollection(); + mStMuDst->set(this); + } if (!mFcsCollection) { mFcsCollection=new StMuFcsCollection(); @@ -1049,7 +1049,7 @@ void StMuDstMaker::fillTrees(StEvent* ev, StMuCut* cut){ fillDetectorStates(ev); fillEmc(ev); fillPmd(ev); - // fillFms(ev); + fillFms(ev); fillRHICf(ev); fillFcs(ev); fillFtt(ev); diff --git a/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx b/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx index 2d97a49bfb0..716b272e824 100644 --- a/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx +++ b/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.cxx @@ -3,14 +3,7 @@ #include "StEvent/StFwdTrack.h" -void StMuFwdTrackSeedPoint::set( StFwdTrackSeedPoint* sp ){ - mXYZ.SetXYZ( sp->mXYZ.x(), sp->mXYZ.y(), sp->mXYZ.z() ); - mSector = sp->mSector; - mTrackId = sp->mTrackId; - memcpy( mCov, sp->mCov, sizeof( mCov ) ); - } - -StMuFwdTrack::StMuFwdTrack() : mDidFitConverge(0),mDidFitConvergeFully(0),mNumberOfFailedPoints(0),mNumberOfSeedPoints(0),mNumberOfFitPoints(0),mChi2(0),mNDF(0),mPval(0),mCharge(0),mPrimaryMomentum(0,0,0),mIdTruth(0),mQATruth(0) { +StMuFwdTrack::StMuFwdTrack() { } @@ -26,15 +19,6 @@ void StMuFwdTrack::set( StFwdTrack * evTrack) { mCharge = evTrack->charge(); mPrimaryMomentum = TVector3( evTrack->momentum().x(), evTrack->momentum().y(), evTrack->momentum().z() ); - mIdTruth = evTrack->idTruth(); - mQATruth = evTrack->qaTruth(); - - auto dca = evTrack->dca(); - setDCA( TVector3( dca.x(), dca.y(), dca.z() ) ); - - // copy the vertex index over - mVtxIndex = evTrack->vertexIndex(); - //copy the projections for ( auto proj : evTrack->mProjections ){ mProjections.push_back( @@ -44,12 +28,16 @@ void StMuFwdTrack::set( StFwdTrack * evTrack) { //copy the FTT Seed Points for ( auto sp : evTrack->mFTTPoints ){ - mFTTPoints.push_back(StMuFwdTrackSeedPoint(&sp)); + mFTTPoints.push_back( + StMuFwdTrackSeedPoint( TVector3( sp.mXYZ.x(), sp.mXYZ.y(), sp.mXYZ.z() ), sp.mSector, sp.mTrackId, sp.mCov ) + ); } //copy the FST Seed Points for ( auto sp : evTrack->mFSTPoints ){ - mFSTPoints.push_back(StMuFwdTrackSeedPoint(&sp)); + mFSTPoints.push_back( + StMuFwdTrackSeedPoint( TVector3( sp.mXYZ.x(), sp.mXYZ.y(), sp.mXYZ.z() ), sp.mSector, sp.mTrackId, sp.mCov ) + ); } } diff --git a/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h b/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h index 74b1461b2d3..11dad825e43 100644 --- a/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h +++ b/StRoot/StMuDSTMaker/COMMON/StMuFwdTrack.h @@ -16,7 +16,10 @@ #include "StMuFcsCluster.h" + class StFwdTrack; + + struct StMuFwdTrackProjection : public TObject { StMuFwdTrackProjection() {} StMuFwdTrackProjection ( const StMuFwdTrackProjection & other) { @@ -65,39 +68,17 @@ struct StMuFwdTrackProjection : public TObject { ClassDef(StMuFwdTrackProjection, 1) }; -class StFwdTrackSeedPoint; struct StMuFwdTrackSeedPoint : public TObject{ StMuFwdTrackSeedPoint() {} StMuFwdTrackSeedPoint( TVector3 xyz, short sec, unsigned short trackId, float cov[9] ){ - set( xyz, sec, trackId, cov ); - } - StMuFwdTrackSeedPoint( StFwdTrackSeedPoint *sp ){ - set( sp ); - } - - // setter - void set( TVector3 xyz, - short sec, - unsigned short trackId, - float cov[9] ){ mXYZ = xyz; mSector = sec; mTrackId = trackId; memcpy( mCov, cov, sizeof( mCov )); } - // setter from StFwdTrackSeedPoint - void set( StFwdTrackSeedPoint *sp ); - - // copy ctor - StMuFwdTrackSeedPoint( const StMuFwdTrackSeedPoint & other ){ - mXYZ = other.mXYZ; - mSector = other.mSector; - mTrackId = other.mTrackId; - memcpy( mCov, other.mCov, sizeof( mCov ) ); - } TVector3 mXYZ; unsigned short mTrackId; @@ -140,9 +121,6 @@ class StMuFwdTrack : public TObject { // Number of points used in the track seed step short numberOfSeedPoints() const; - UShort_t idTruth() const { return mIdTruth; } - UShort_t qaTruth() const { return mQATruth; } - TVector3 dca() const { return TVector3( mDCAXY, mDCAXY, mDCAZ ); } void setPrimaryMomentum( TVector3 mom ) { mPrimaryMomentum = mom; } @@ -155,41 +133,46 @@ class StMuFwdTrack : public TObject { void setNDF( float lNDF ) { mNDF = lNDF;} void setPval( float lPval ) { mPval = lPval;} void setCharge( short lCharge ) { mCharge = lCharge;} - void setMc( UShort_t idt, UShort_t qual ) { mIdTruth = idt; mQATruth = qual; } - void setDCA( float dca[3] ) { mDCAXY = sqrt(dca[0]*dca[0]+dca[1]*dca[1]); mDCAZ = dca[2]; } - void setDCA( TVector3 dca ) { mDCAXY = sqrt(dca.X()*dca.X() + dca.Y()*dca.Y()); mDCAZ = dca.Z(); } + + // ECAL clusters + // StPtrVecFcsCluster& ecalClusters(); + // const StPtrVecFcsCluster& ecalClusters() const; + // void addEcalCluster(StFcsCluster* p); + // void sortEcalClusterByET(); + // // HCAL clusters + // StPtrVecFcsCluster& hcalClusters(); + // const StPtrVecFcsCluster& hcalClusters() const; + // void addHcalCluster(StFcsCluster* p); + // void sortHcalClusterByET(); + + // vector void addEcalCluster( StMuFcsCluster* clu); void addHcalCluster( StMuFcsCluster* clu); - // FCS Cluster matches TRefArray mEcalClusters; TRefArray mHcalClusters; protected: // Track quality and convergence - bool mDidFitConverge; // == 0 if the fit did not converge - bool mDidFitConvergeFully; // == 0 if the fit did not converge fully - short mNumberOfFailedPoints; // Number of points that failed to be fitted - short mNumberOfSeedPoints; // Number of points used in the track seed step - short mNumberOfFitPoints; // Number of fit points used by GenFit - float mChi2; // Chi^2 of the fit - float mNDF; // Number of degrees of freedom of the fit - float mPval; // P-value of the fit - short mCharge; // Charge of the track - TVector3 mPrimaryMomentum; // Momentum of the track at the primary vertex + bool mDidFitConverge; + bool mDidFitConvergeFully; + short mNumberOfFailedPoints; + short mNumberOfSeedPoints; + short mNumberOfFitPoints; + float mChi2; + float mNDF; + float mPval; + short mCharge; + TVector3 mPrimaryMomentum; - /// MC track id - UShort_t mIdTruth; - /// MC track quality (percentage of hits coming from corresponding MC track) - UShort_t mQATruth; - float mDCAXY; // DCA XY to the primary vertex - float mDCAZ; // DCA Z to the primary vertex - UChar_t mVtxIndex; // Index of the vertex in the event + // StPtrVecFcsCluster mEcalClusters; + // StPtrVecFcsCluster mHcalClusters; + + ClassDef(StMuFwdTrack,2) - ClassDef(StMuFwdTrack,3) }; #endif diff --git a/StRoot/StPicoDstMaker/StPicoDstMaker.cxx b/StRoot/StPicoDstMaker/StPicoDstMaker.cxx index fbd57892610..4e114feba2a 100644 --- a/StRoot/StPicoDstMaker/StPicoDstMaker.cxx +++ b/StRoot/StPicoDstMaker/StPicoDstMaker.cxx @@ -40,8 +40,6 @@ #include "StEvent/StTriggerData.h" #include "StEvent/StEnumerations.h" #include "StEvent/StL0Trigger.h" -#include "StEvent/StFwdTrackCollection.h" -#include "StEvent/StFwdTrack.h" #include "StMuDSTMaker/COMMON/StMuDst.h" #include "StMuDSTMaker/COMMON/StMuEvent.h" @@ -61,9 +59,6 @@ #include "StMuDSTMaker/COMMON/StMuETofHeader.h" #include "StMuDSTMaker/COMMON/StMuMcTrack.h" #include "StMuDSTMaker/COMMON/StMuMcVertex.h" -#include "StMuDSTMaker/COMMON/StMuFcsCollection.h" -#include "StMuDSTMaker/COMMON/StMuFcsHit.h" -#include "StMuDSTMaker/COMMON/StMuFcsCluster.h" #include "StTriggerUtilities/StTriggerSimuMaker.h" #include "StTriggerUtilities/Bemc/StBemcTriggerSimu.h" @@ -75,7 +70,6 @@ #include "StEmcRawMaker/StBemcTables.h" #include "StFmsDbMaker/StFmsDbMaker.h" -#include "StFcsDbMaker/StFcsDb.h" #include "tables/St_mtdModuleToQTmap_Table.h" #include "tables/St_mtdQTSlewingCorr_Table.h" @@ -100,9 +94,6 @@ #include "StPicoEvent/StPicoBEmcSmdPHit.h" #include "StPicoEvent/StPicoETofHit.h" #include "StPicoEvent/StPicoETofPidTraits.h" -#include "StPicoEvent/StPicoFwdTrack.h" -#include "StPicoEvent/StPicoFcsHit.h" -#include "StPicoEvent/StPicoFcsCluster.h" #include "StPicoEvent/StPicoMcVertex.h" #include "StPicoEvent/StPicoMcTrack.h" #include "StPicoEvent/StPicoArrays.h" @@ -254,9 +245,6 @@ void StPicoDstMaker::streamerOff() { StPicoTrackCovMatrix::Class()->IgnoreTObjectStreamer(); StPicoETofHit::Class()->IgnoreTObjectStreamer(); StPicoETofPidTraits::Class()->IgnoreTObjectStreamer(); - StPicoFwdTrack::Class()->IgnoreTObjectStreamer(); - StPicoFcsHit::Class()->IgnoreTObjectStreamer(); - StPicoFcsCluster::Class()->IgnoreTObjectStreamer(); StPicoMcVertex::Class()->IgnoreTObjectStreamer(); StPicoMcTrack::Class()->IgnoreTObjectStreamer(); } @@ -905,9 +893,6 @@ Int_t StPicoDstMaker::MakeWrite() { fillEpdHits(); fillBbcHits(); fillETofHits(); - fillFwdTracks(); - fillFcsHits(); - fillFcsClusters(); // Could be a good idea to move this call to Init() or InitRun() StFmsDbMaker* fmsDbMaker = static_cast(GetMaker("fmsDb")); @@ -2517,103 +2502,6 @@ void StPicoDstMaker::fillMtdHits() { } //while (triggerPos.size() > 0) } -//_________________ -void StPicoDstMaker::fillFwdTracks() { - - StEvent *evt = (StEvent *)GetDataSet("StEvent"); - if ( evt ){ - StFwdTrackCollection * evc = evt->fwdTrackCollection(); - if ( !evc ){ - LOG_ERROR << "null FwdTrackCollection" << endm; - return; - } - const StSPtrVecFwdTrack& evTracks = evc->tracks(); - LOG_INFO << "Adding " << evc->numberOfTracks() << " StFwdTracks from StEvent to PicoDst" << endm; - for ( size_t i = 0; i < evc->numberOfTracks(); i++ ){ - StFwdTrack * evTrack = evTracks[i]; - StPicoFwdTrack picoFwdTrack; - // Set the PicoDst attributes - picoFwdTrack.setMomentum( evTrack->momentum().x(), evTrack->momentum().y(), evTrack->momentum().z() ); - picoFwdTrack.setNumberOfFitPoints( evTrack->numberOfFitPoints() * evTrack->charge() ); - picoFwdTrack.setNumberOfSeedPoints( evTrack->numberOfSeedPoints() ); - picoFwdTrack.setChi2( evTrack->chi2() ); - // Add the PicoDst object to the PicoArray - int counter = mPicoArrays[StPicoArrays::FwdTrack]->GetEntries(); - picoFwdTrack.setId( counter ); - new((*(mPicoArrays[StPicoArrays::FwdTrack]))[counter]) StPicoFwdTrack(picoFwdTrack); - } - } else { - LOG_WARN << "Cannot get Fwd Tracks from StEvent" << endm; - } -} //fillFwdTracks - -//_________________ -void StPicoDstMaker::fillFcsClusters() { - StFcsDb* fcsDb = static_cast(GetDataSet("fcsDb")); - if( !fcsDb ) { - LOG_ERROR << "Cannot get StFcsDb object" << endm; - return; - } - StMuFcsCollection * muFcs = mMuDst->muFcsCollection(); - if ( !muFcs ) { - LOG_ERROR << "Cannot get Fcs Collection from MuDst" << endm; - return; - } - TIter next(muFcs->getClusterArray()); - StMuFcsCluster* muCluster(NULL); - while ((muCluster = static_cast(next()))) { - int counter = mPicoArrays[StPicoArrays::FcsCluster]->GetEntries(); - StPicoFcsCluster picoFcsCluster; - picoFcsCluster.setId(counter); - picoFcsCluster.setDetectorId(muCluster->detectorId()); - picoFcsCluster.setCategory(muCluster->category()); - picoFcsCluster.setNTowers(muCluster->nTowers()); - picoFcsCluster.setEnergy(muCluster->energy()); - picoFcsCluster.setX(muCluster->x()); - picoFcsCluster.setY(muCluster->y()); - picoFcsCluster.setSigmaMin(muCluster->sigmaMin()); - picoFcsCluster.setSigmaMax(muCluster->sigmaMax()); - picoFcsCluster.setTheta(muCluster->theta()); - picoFcsCluster.setChi2Ndf1Photon(muCluster->chi2Ndf1Photon()); - picoFcsCluster.setChi2Ndf2Photon(muCluster->chi2Ndf2Photon()); - double zVertex=picoDst()->event()->primaryVertex().z(); - StThreeVectorD xyz=fcsDb->getStarXYZ(muCluster->detectorId(), muCluster->x(), muCluster->y()); - StLorentzVectorD lv = fcsDb->getLorentzVector(xyz, muCluster->energy(), zVertex); - picoFcsCluster.setFourMomentum(lv.px(),lv.py(),lv.pz(),lv.e()); - new((*(mPicoArrays[StPicoArrays::FcsCluster]))[counter]) StPicoFcsCluster(picoFcsCluster); - } - LOG_INFO << "StPicoDstMaker::fillFcsClusters filled " << mPicoArrays[StPicoArrays::FcsCluster]->GetEntries() << endm; -}//fillFcsClusters - -//_________________ -void StPicoDstMaker::fillFcsHits() { - StFcsDb* fcsDb = static_cast(GetDataSet("fcsDb")); - if( !fcsDb ) { - LOG_ERROR << "Cannot get StFcsDb object" << endm; - return; - } - StMuFcsCollection * muFcs = mMuDst->muFcsCollection(); - if ( !muFcs ) { - LOG_ERROR << "Cannot get Fcs Collection from MuDst" << endm; - return; - } - TIter next(muFcs->getHitArray()); - StMuFcsHit* muHit(NULL); - while ((muHit = static_cast(next()))) { - int counter = mPicoArrays[StPicoArrays::FcsHit]->GetEntries(); - StPicoFcsHit picoFcsHit; - picoFcsHit.setIndex(counter); - picoFcsHit.setDetectorId(muHit->detectorId()); - picoFcsHit.setId(muHit->id()); - double zVertex=picoDst()->event()->primaryVertex().z(); - StThreeVectorD xyz = fcsDb->getStarXYZ(muHit->detectorId(), muHit->id()); - StLorentzVectorD lv = fcsDb->getLorentzVector(xyz, muHit->energy(), zVertex); - picoFcsHit.setFourMomentum(lv.px(),lv.py(),lv.pz(),lv.e()); - new((*(mPicoArrays[StPicoArrays::FcsHit]))[counter]) StPicoFcsHit(picoFcsHit); - } - LOG_INFO << "StPicoDstMaker::fillFcsHits filled " << mPicoArrays[StPicoArrays::FcsHit]->GetEntries() << endm; -}//fillFcsHit - #if !defined (__TFG__VERSION__) /** diff --git a/StRoot/StPicoDstMaker/StPicoDstMaker.h b/StRoot/StPicoDstMaker/StPicoDstMaker.h index 0566fc85cd5..e5f91085fb2 100644 --- a/StRoot/StPicoDstMaker/StPicoDstMaker.h +++ b/StRoot/StPicoDstMaker/StPicoDstMaker.h @@ -225,12 +225,6 @@ class StPicoDstMaker : public StMaker { void fillBbcHits(); /// Fill ETOF information void fillETofHits(); - /// Fill Fwd Track information - void fillFwdTracks(); - /// Fill FcsHits information - void fillFcsHits(); - /// Fill FcsClusters information - void fillFcsClusters(); /// Fill MC vertex information void fillMcVertices(); /// Fill MC track information diff --git a/StRoot/StPicoEvent/StPicoArrays.cxx b/StRoot/StPicoEvent/StPicoArrays.cxx index 3e493522ce0..2038c048778 100644 --- a/StRoot/StPicoEvent/StPicoArrays.cxx +++ b/StRoot/StPicoEvent/StPicoArrays.cxx @@ -25,11 +25,8 @@ const char* StPicoArrays::picoArrayNames [NAllPicoArrays] = { "Event", "BEmcSmdPHit", "ETofHit", "ETofPidTraits", - "McVertex", - "McTrack", - "FwdTracks", - "FcsHits", - "FcsClusters" + "McVertex", + "McTrack" }; // ARRAY TYPES @@ -52,11 +49,8 @@ const char* StPicoArrays::picoArrayTypes [NAllPicoArrays] = { "StPicoEvent", "StPicoBEmcSmdPHit", "StPicoETofHit", "StPicoETofPidTraits", - "StPicoMcVertex", - "StPicoMcTrack", - "StPicoFwdTrack", - "StPicoFcsHit", - "StPicoFcsCluster" + "StPicoMcVertex", + "StPicoMcTrack" }; // ARRAY SIZES @@ -82,11 +76,8 @@ int StPicoArrays::picoArraySizes [NAllPicoArrays] = { 1, // StPicoEvent 100, // StPicoBEmcSmdPHit 100, // StPicoETofHit 100, // StPicoETofPidTraits - 10, // StPicoMcVertex - 1000, // StPicoMcTrack - 10, // StPicoFwdTrack - 200, // StPicoFcsHit - 100 // StPicoFcsCluster + 10, // StPicoMcVertex + 1000 // StPicoMcTrack }; //_________________ diff --git a/StRoot/StPicoEvent/StPicoArrays.h b/StRoot/StPicoEvent/StPicoArrays.h index a107091cdcd..aad476f02d0 100644 --- a/StRoot/StPicoEvent/StPicoArrays.h +++ b/StRoot/StPicoEvent/StPicoArrays.h @@ -17,7 +17,7 @@ class StPicoArrays { StPicoArrays(); /// Should be changed to constexpr once ROOT 6 is available at STAR - enum { NAllPicoArrays = 23}; + enum { NAllPicoArrays = 20}; /// Names of the TBranches in the TTree/File static const char* picoArrayNames[NAllPicoArrays]; @@ -32,9 +32,8 @@ class StPicoArrays { enum TypeIndex { Event=0, Track, EmcTrigger, MtdTrigger, BTowHit, BTofHit, MtdHit, BbcHit, EpdHit, FmsHit, BEmcPidTraits, BTofPidTraits, MtdPidTraits, TrackCovMatrix, - BEmcSmdEHit, BEmcSmdPHit, ETofHit, ETofPidTraits, - McVertex, McTrack, - FwdTrack, FcsHit, FcsCluster }; + BEmcSmdEHit, BEmcSmdPHit, ETofHit, ETofPidTraits, + McVertex, McTrack }; }; #endif diff --git a/StRoot/StPicoEvent/StPicoDst.cxx b/StRoot/StPicoEvent/StPicoDst.cxx index 920e1e781ca..7c243deed22 100644 --- a/StRoot/StPicoEvent/StPicoDst.cxx +++ b/StRoot/StPicoEvent/StPicoDst.cxx @@ -19,7 +19,6 @@ #include "StPicoBEmcSmdPHit.h" #include "StPicoETofHit.h" #include "StPicoETofPidTraits.h" -#include "StPicoFwdTrack.h" #include "StPicoMcVertex.h" #include "StPicoMcTrack.h" #include "StPicoDst.h" //MUST be the last one @@ -329,19 +328,3 @@ void StPicoDst::printETofPidTraits() { LOG_INFO << endm; } -//_________________ -void StPicoDst::printFwdTracks() { - if(numberOfFwdTracks() == 0) { - LOG_INFO << "No Fwd tracks found!" << endm; - return; - } - - LOG_INFO << "\n+++++++++ fwd track list ( " << numberOfFwdTracks() << " entries )\n\n"; - for(UInt_t iTrk=0; iTrkPrint(); - LOG_INFO << "\n"; - } - - LOG_INFO << endm; -} diff --git a/StRoot/StPicoEvent/StPicoDst.h b/StRoot/StPicoEvent/StPicoDst.h index 129df01e6e3..7448d35b7ec 100644 --- a/StRoot/StPicoEvent/StPicoDst.h +++ b/StRoot/StPicoEvent/StPicoDst.h @@ -33,9 +33,6 @@ class StPicoBEmcSmdEHit; class StPicoBEmcSmdPHit; class StPicoETofHit; class StPicoETofPidTraits; -class StPicoFwdTrack; -class StPicoFcsHit; -class StPicoFcsCluster; class StPicoMcVertex; class StPicoMcTrack; @@ -96,12 +93,6 @@ class StPicoDst { static StPicoBEmcSmdPHit* bemcSmdPHit(Int_t i) { return (StPicoBEmcSmdPHit*)picoArrays[StPicoArrays::BEmcSmdPHit]->UncheckedAt(i); } /// Return pointer to i-th etof hit static StPicoETofHit* etofHit(Int_t i) { return (StPicoETofHit*)picoArrays[StPicoArrays::ETofHit]->UncheckedAt(i); } - /// Return pointer to i-th fwd track - static StPicoFwdTrack* fwdTrack(Int_t i) { return (StPicoFwdTrack*)picoArrays[StPicoArrays::FwdTrack]->UncheckedAt(i); } - /// Return pointer to i-th fcs Hit - static StPicoFcsHit* fcsHit(Int_t i) { return (StPicoFcsHit*)picoArrays[StPicoArrays::FcsHit]->UncheckedAt(i); } - /// Return pointer to i-th fcs Cluster - static StPicoFcsCluster* fcsCluster(Int_t i) { return (StPicoFcsCluster*)picoArrays[StPicoArrays::FcsCluster]->UncheckedAt(i); } /// Return pointer to i-th etof pidTraits static StPicoETofPidTraits* etofPidTraits(Int_t i) { return (StPicoETofPidTraits*)picoArrays[StPicoArrays::ETofPidTraits]->UncheckedAt(i); } /// Return pointer to i-th MC vertex @@ -143,12 +134,6 @@ class StPicoDst { static UInt_t numberOfETofHits() { return picoArrays[StPicoArrays::ETofHit]->GetEntriesFast(); } /// Return number of ETOF PID traits static UInt_t numberOfETofPidTraits() { return picoArrays[StPicoArrays::ETofPidTraits]->GetEntriesFast(); } - /// Return number of Fwd Tracks - static UInt_t numberOfFwdTracks() { return picoArrays[StPicoArrays::FwdTrack]->GetEntriesFast(); } - /// Return number of FcsHits - static UInt_t numberOfFcsHits() { return picoArrays[StPicoArrays::FcsHit]->GetEntriesFast(); } - /// Return number of FcsClusters - static UInt_t numberOfFcsClusters() { return picoArrays[StPicoArrays::FcsCluster]->GetEntriesFast(); } /// Return number of MC vertices static UInt_t numberOfMcVertices() { return picoArrays[StPicoArrays::McVertex]->GetEntriesFast(); } /// Return number of MC tracks @@ -184,8 +169,6 @@ class StPicoDst { static void printETofHits(); /// Print ETOF PID trait info static void printETofPidTraits(); - /// Print Fwd track info - static void printFwdTracks(); /// Print MC vertex info static void printMcVertices(); /// Print MC track info diff --git a/StRoot/StPicoEvent/StPicoDstLinkDef.h b/StRoot/StPicoEvent/StPicoDstLinkDef.h index 9a69d010579..c81c8b95ef2 100644 --- a/StRoot/StPicoEvent/StPicoDstLinkDef.h +++ b/StRoot/StPicoEvent/StPicoDstLinkDef.h @@ -26,9 +26,6 @@ #pragma link C++ class StPicoDstReader+; #pragma link C++ class StPicoETofHit+; #pragma link C++ class StPicoETofPidTraits+; -#pragma link C++ class StPicoFwdTrack+; -#pragma link C++ class StPicoFcsHit+; -#pragma link C++ class StPicoFcsCluster+; #pragma link C++ class StPicoDst+; // StarClassLibrary adopted classes diff --git a/StRoot/StPicoEvent/StPicoDstReader.cxx b/StRoot/StPicoEvent/StPicoDstReader.cxx index 2222fa89a28..8a388e9f5ee 100644 --- a/StRoot/StPicoEvent/StPicoDstReader.cxx +++ b/StRoot/StPicoEvent/StPicoDstReader.cxx @@ -30,9 +30,6 @@ #include "StPicoBEmcSmdPHit.h" #include "StPicoETofHit.h" #include "StPicoETofPidTraits.h" -#include "StPicoFwdTrack.h" -#include "StPicoFcsHit.h" -#include "StPicoFcsCluster.h" #include "StPicoMcVertex.h" #include "StPicoMcTrack.h" #include "StPicoArrays.h" @@ -134,9 +131,6 @@ void StPicoDstReader::streamerOff() { StPicoBEmcSmdPHit::Class()->IgnoreTObjectStreamer(); StPicoETofHit::Class()->IgnoreTObjectStreamer(); StPicoETofPidTraits::Class()->IgnoreTObjectStreamer(); - StPicoFwdTrack::Class()->IgnoreTObjectStreamer(); - StPicoFcsHit::Class()->IgnoreTObjectStreamer(); - StPicoFcsCluster::Class()->IgnoreTObjectStreamer(); StPicoMcVertex::Class()->IgnoreTObjectStreamer(); StPicoMcTrack::Class()->IgnoreTObjectStreamer(); } diff --git a/StRoot/StPicoEvent/StPicoFcsCluster.cxx b/StRoot/StPicoEvent/StPicoFcsCluster.cxx deleted file mode 100644 index 62b3386c013..00000000000 --- a/StRoot/StPicoEvent/StPicoFcsCluster.cxx +++ /dev/null @@ -1,39 +0,0 @@ -#include "StPicoFcsCluster.h" -#include -#include "StPicoMessMgr.h" - -// ROOT headers -#include "TMath.h" - -ClassImp(StPicoFcsCluster) - -StPicoFcsCluster::StPicoFcsCluster() : TObject() { - /* No Op*/ -} - -StPicoFcsCluster::StPicoFcsCluster(const StPicoFcsCluster &clu){ - mId=clu.mId; - mDetectorId=clu.mDetectorId; - mCategory=clu.mCategory; - mNTowers=clu.mNTowers; - mX=clu.mX; - mY=clu.mY; - mSigmaMin=clu.mSigmaMin; - mSigmaMax=clu.mSigmaMax; - mTheta=clu.mTheta; - mChi2Ndf1Photon=clu.mChi2Ndf1Photon; - mChi2Ndf2Photon=clu.mChi2Ndf2Photon; - mFourMomentumX=clu.mFourMomentumX; - mFourMomentumY=clu.mFourMomentumY; - mFourMomentumZ=clu.mFourMomentumZ; - mFourMomentumT=clu.mFourMomentumT; -} - -StPicoFcsCluster::~StPicoFcsCluster(){ - -} - -//_________________ -void StPicoFcsCluster::Print(const Char_t* option __attribute__((unused))) const { - -} diff --git a/StRoot/StPicoEvent/StPicoFcsCluster.h b/StRoot/StPicoEvent/StPicoFcsCluster.h deleted file mode 100644 index 4160cef1040..00000000000 --- a/StRoot/StPicoEvent/StPicoFcsCluster.h +++ /dev/null @@ -1,80 +0,0 @@ -/*************************************************************************** - * - * Author: jdb, Feb 2022 - *************************************************************************** - * - * Description: StPicoFcsCluster stores the Fcs Clusters - * - **************************************************************************/ -#ifndef StPicoFcsCluster_hh -#define StPicoFcsCluster_hh - -#include -#include -#include "TVector3.h" -#include "TLorentzVector.h" - - -class StPicoFcsCluster : public TObject { - -public: - /// Constructor - StPicoFcsCluster( ); - /// Copy constructor - StPicoFcsCluster(const StPicoFcsCluster &fwdTrack); - /// Destructor - virtual ~StPicoFcsCluster(); - - virtual void Print(const Char_t *option = "") const; - /// Return unique Id of the track - Int_t id() const { return mId; } - unsigned short detectorId() const { return mDetectorId; } - int category() const { return mCategory; } - int nTowers() const { return mNTowers; } - float energy() const { return mFourMomentumT; } // Energy - float x() const { return mX; } // Mean x ("center of gravity") in local grid coordinate (1st moment). - float y() const { return mY; } // Mean y ("center of gravity") in local grid coordinate (1st moment). - float sigmaMax() const { return mSigmaMax; } // Maximum 2nd moment (along major axis). - float sigmaMin() const { return mSigmaMin; } // Minimum 2nd moment. - float theta() const { return mTheta; } // Angle in x-y plane that defines the direction of least-2nd-sigma - float chi2Ndf1Photon() const { return mChi2Ndf1Photon; } // chi^2/ndf for 1-photon fit to the cluster. - float chi2Ndf2Photon() const { return mChi2Ndf2Photon; } // chi^2/ndf for 2-photon fit to the cluster. - const TLorentzVector fourMomentum() const { return TLorentzVector( mFourMomentumX, mFourMomentumY, mFourMomentumZ, mFourMomentumT ); } // Cluster four-momentum (px, py, pz, E) - - void setId(int cluid) { mId = (UShort_t)cluid; } - void setDetectorId(unsigned short detector) { mDetectorId=(UShort_t)detector; } - void setCategory(int catag) { mCategory = catag; } - void setNTowers(int numbTower) { mNTowers = (UShort_t)numbTower; } - void setEnergy(float energy) { mFourMomentumT = energy; } - void setX(float x0) { mX = x0; } - void setY(float y0) { mY = y0; } - void setSigmaMin(float sigmaMin) { mSigmaMin = sigmaMin; } - void setSigmaMax(float sigmaMax) { mSigmaMax = sigmaMax; } - void setTheta(float theta) { mTheta = theta; } - void setChi2Ndf1Photon(float chi2ndfph1) { mChi2Ndf1Photon = chi2ndfph1; } - void setChi2Ndf2Photon(float chi2ndfph2) { mChi2Ndf2Photon = chi2ndfph2;} - void setFourMomentum(float px, float py, float pz, float e) { mFourMomentumX = px; mFourMomentumY = py; mFourMomentumZ = pz; mFourMomentumT = e; } - void setFourMomentum(TLorentzVector p4) { mFourMomentumX = p4.X(); mFourMomentumY = p4.Y(); mFourMomentumZ = p4.Z(); mFourMomentumT = p4.T(); } - -protected: - UShort_t mId=0; // Eventwise cluster ID - UShort_t mDetectorId=0; // Detector starts from 1 - Int_t mCategory=0; // Category of cluster (see StMuFcsClusterCategory) - UShort_t mNTowers=0; // Number of non-zero-energy tower hits in the cluster - Float_t mX=0.0; // Mean x ("center of gravity") in local grid coordinate (1st moment) - Float_t mY=0.0; // Mean y ("center of gravity") in local grid coordinate (1st moment) - Float_t mSigmaMin=0.0; // Minimum 2nd moment - Float_t mSigmaMax=0.0; // Maximum 2nd moment (along major axis) - Float_t mTheta=0.0; //Angle in x-y plane that defines the direction of least-2nd-sigma - Float_t mChi2Ndf1Photon=0.0; // χ2 / ndf for 1-photon fit - Float_t mChi2Ndf2Photon=0.0; // χ2 / ndf for 2-photon fit - Float_t mFourMomentumX=0.0; - Float_t mFourMomentumY=0.0; - Float_t mFourMomentumZ=0.0; - Float_t mFourMomentumT=0.0; - - ClassDef(StPicoFcsCluster, 2) -}; - -#endif - diff --git a/StRoot/StPicoEvent/StPicoFcsHit.cxx b/StRoot/StPicoEvent/StPicoFcsHit.cxx deleted file mode 100644 index f372e59709d..00000000000 --- a/StRoot/StPicoEvent/StPicoFcsHit.cxx +++ /dev/null @@ -1,27 +0,0 @@ -#include "StPicoFcsHit.h" -#include -#include "StPicoMessMgr.h" - -// ROOT headers -#include "TMath.h" - -ClassImp(StPicoFcsHit) - -StPicoFcsHit::StPicoFcsHit() : TObject() { -} - -StPicoFcsHit::StPicoFcsHit(const StPicoFcsHit &hit){ - mIndex=hit.mIndex; - mDetectorId=hit.mDetectorId; - mId=hit.mId; - mFourMomentumX=hit.mFourMomentumX; - mFourMomentumY=hit.mFourMomentumY; - mFourMomentumZ=hit.mFourMomentumZ; - mFourMomentumT=hit.mFourMomentumT; -} - -StPicoFcsHit::~StPicoFcsHit(){ -} - -void StPicoFcsHit::Print(const Char_t* option __attribute__((unused))) const { -} diff --git a/StRoot/StPicoEvent/StPicoFcsHit.h b/StRoot/StPicoEvent/StPicoFcsHit.h deleted file mode 100644 index 265b4ae5e44..00000000000 --- a/StRoot/StPicoEvent/StPicoFcsHit.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * - * Author: jdb, Feb 2022 - *************************************************************************** - * - * Description: StPicoFcsHit stores the Fcs Hits - * - **************************************************************************/ -#ifndef StPicoFcsHit_hh -#define StPicoFcsHit_hh - -#include -#include -#include "TVector3.h" -#include "TLorentzVector.h" - -class StPicoFcsHit : public TObject { - -public: - /// Constructor - StPicoFcsHit(); - /// Copy constructor - StPicoFcsHit(const StPicoFcsHit &fwdTrack); - /// Destructor - virtual ~StPicoFcsHit(); - - virtual void Print(const Char_t *option = "") const; - Int_t index() const { return mIndex; } // Return unique Index of the hit - unsigned short detectorId() const { return mDetectorId; } - Int_t id() const { return mId; } // Id of the hit winthin detectorId - float energy() const { return mFourMomentumT; } // Energy - const TLorentzVector fourMomentum() const { return TLorentzVector( mFourMomentumX, mFourMomentumY, mFourMomentumZ, mFourMomentumT ); } // Hit four-momentum (px, py, pz, E) - - void setIndex(int index) { mIndex = (UShort_t)index; } - void setDetectorId(unsigned short detector) { mDetectorId=(UShort_t)detector; } - void setId(int id) { mIndex = (UShort_t)id; } - void setFourMomentum(float px, float py, float pz, float e) { mFourMomentumX = px; mFourMomentumY = py; mFourMomentumZ = pz; mFourMomentumT = e; } - void setFourMomentum(TLorentzVector p4) { mFourMomentumX = p4.X(); mFourMomentumY = p4.Y(); mFourMomentumZ = p4.Z(); mFourMomentumT = p4.T(); } - -protected: - UShort_t mIndex=0; // Eventwise Hit Index - UShort_t mDetectorId=0; // DetectorId - UShort_t mId=0; // Id of the hit winthin a detectorId - Float_t mFourMomentumX=0.0; // Four momentum component X - Float_t mFourMomentumY=0.0; // Four momentum component Y - Float_t mFourMomentumZ=0.0; // Four momentum component Z - Float_t mFourMomentumT=0.0; // Four momentum component T - - ClassDef(StPicoFcsHit, 1) -}; - -#endif - diff --git a/StRoot/StPicoEvent/StPicoFwdTrack.cxx b/StRoot/StPicoEvent/StPicoFwdTrack.cxx deleted file mode 100644 index a381dc9fc64..00000000000 --- a/StRoot/StPicoEvent/StPicoFwdTrack.cxx +++ /dev/null @@ -1,55 +0,0 @@ -#include "StPicoFwdTrack.h" -#include -#include "StPicoMessMgr.h" - -// ROOT headers -#include "TMath.h" - -ClassImp(StPicoFwdTrack) - -StPicoFwdTrack::StPicoFwdTrack() : TObject() { - /* No Op*/ -} - -StPicoFwdTrack::StPicoFwdTrack(const StPicoFwdTrack &fwdTrack){ - mId = fwdTrack.mId; - mNumberOfSeedPoints = fwdTrack.mNumberOfSeedPoints; - mNumberOfFitPoints = fwdTrack.mNumberOfFitPoints; - mChi2 = fwdTrack.mChi2; - - mMomentumX = fwdTrack.mMomentumX; - mMomentumY = fwdTrack.mMomentumY; - mMomentumZ = fwdTrack.mMomentumZ; - mStatus = fwdTrack.mStatus; - - mIdTruth = fwdTrack.mIdTruth; - mQATruth = fwdTrack.mQATruth; - - for ( size_t i = 0 ; i < fwdTrack.mEcalMatchIndex.size(); i++ ){ - addEcalCluster( fwdTrack.mEcalMatchIndex[i] ); - } - for ( size_t i = 0 ; i < fwdTrack.mHcalMatchIndex.size(); i++ ){ - addHcalCluster( fwdTrack.mHcalMatchIndex[i] ); - } -} - -StPicoFwdTrack::~StPicoFwdTrack(){ - -} - -//_________________ -void StPicoFwdTrack::Print(const Char_t* option __attribute__((unused))) const { - LOG_INFO << " chi2: " << chi2() << "\n" - << "pMom: " << momentum().X() << " " << momentum().Y() << " " << momentum().Z() << "\n" - << "nHitsFit: " << numberOfFitPoints() - << " numberOfSeedPoints: " << numberOfSeedPoints() << "\n" - // << "idTruth: " << idTruth() << " qaTruth: " << qaTruth() << "\n" - << endm; -} - -//_________________ -void StPicoFwdTrack::setChi2(Float_t chi2) { - mChi2 = ( (chi2 * 1000.) > std::numeric_limits::max() ? - std::numeric_limits::max() : - (UShort_t)( TMath::Nint( chi2 * 1000. ) ) ); -} \ No newline at end of file diff --git a/StRoot/StPicoEvent/StPicoFwdTrack.h b/StRoot/StPicoEvent/StPicoFwdTrack.h deleted file mode 100644 index 40fc99bdc0d..00000000000 --- a/StRoot/StPicoEvent/StPicoFwdTrack.h +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************** - * - * Author: jdb, Feb 2022 - *************************************************************************** - * - * Description: StPicoFwdTrack stores the Forward tracks built from Fst and Ftt - * - **************************************************************************/ -#ifndef StPicoFwdTrack_hh -#define StPicoFwdTrack_hh - -#include -#include -#include "TVector3.h" -#include "TRefArray.h" - - -class StPicoFwdTrack : public TObject { - -public: - /// Constructor - StPicoFwdTrack( ); - /// Copy constructor - StPicoFwdTrack(const StPicoFwdTrack &fwdTrack); - /// Destructor - virtual ~StPicoFwdTrack(); - - virtual void Print(const Char_t *option = "") const; - /// Return unique Id of the track - Int_t id() const { return mId; } - /// Return chi2 of the track - Float_t chi2() const { return mChi2 / 1000.f; } - /// Return momentum (GeV/c) - TVector3 momentum() const { return TVector3( mMomentumX, mMomentumY, mMomentumZ ); } - /// Return charge of the track (encoded in nHitsFit as: nHitsFit * charge) - Short_t charge() const { return (mNumberOfFitPoints > 0) ? 1 : -1; } - /// Quality of the fit (from status) - bool didFitConverge() const { return (mStatus >= 1); } - bool didFitConvergeFully() const { return (mStatus >= 2); } - /// Return if the track fit converged - Char_t status() const { return mStatus; } - /// Index of the corresponding MC track - Int_t idTruth() const { return mIdTruth; } - /// Qualtiy of the MC track - Int_t qaTruth() const { return mQATruth; } - - // Number of fit points used by GenFit - Int_t numberOfFitPoints() const { return mNumberOfFitPoints; } - // unsigned int numberOfPossibleFitPoints() const; - - // Number of points used in the track seed step - Int_t numberOfSeedPoints() const { return mNumberOfSeedPoints; } - - void setId( Int_t id) { mId = (UShort_t)id; } - void setMomentum( TVector3 mom ) { mMomentumX = mom.X(); mMomentumY = mom.Y(); mMomentumZ = mom.Z(); } - void setMomentum( double px, double py, double pz ) { mMomentumX = (Float_t)px; mMomentumY = (Float_t)py; mMomentumZ = (Float_t)pz; } - void setStatus( UChar_t status ) { mStatus = status;} - void setNumberOfSeedPoints( Int_t lNumberOfSeedPoints ) { mNumberOfSeedPoints = (UChar_t)lNumberOfSeedPoints;} - void setNumberOfFitPoints( Int_t lNumberOfFitPoints ) { mNumberOfFitPoints = (Char_t)lNumberOfFitPoints;} - void setChi2(Float_t chi2); - void addEcalCluster( UChar_t index ) { mEcalMatchIndex.push_back(index); } - void addHcalCluster( UChar_t index ) { mHcalMatchIndex.push_back(index); } - /// Set index of the corresonding MC track - void setMcTruth(Int_t index, Int_t qa) { mIdTruth = (UShort_t)index; mQATruth = (UShort_t)qa; } - -protected: - - // Track quality and convergence - /// Unique track ID - UShort_t mId; - /// Number of points used in seed - UChar_t mNumberOfSeedPoints; - /// Charge * nHitsFit - Char_t mNumberOfFitPoints; - /// Chi2 of the track (encoding = chi2*1000) - UShort_t mChi2; - - /// Px momentum (GeV/c) - Float_t mMomentumX; - /// Py momentum (GeV/c) - Float_t mMomentumY; - /// Pz momentum (GeV/c) - Float_t mMomentumZ; - /// convergence (0=no, 1=converge, 2=converge fully) - UChar_t mStatus; - /// DCA to primary vertex (XY) - Float_t mDCAXY; - /// DCA to primary vertex (Z) - Float_t mDCAZ; - /// Index of primary vertex used in fit (primary tracks only) - UChar_t mVtxIndex; - /// Index of the corresponding Global Track if primary, else USHRT_MAX - UShort_t mGlobalTrackIndex; - - /// ecal match index - std::vector mEcalMatchIndex; - /// hcal match index - std::vector mHcalMatchIndex; - - /// MC track id - UShort_t mIdTruth; - /// MC track quality (percentage of hits coming from corresponding MC track) - UShort_t mQATruth; - - ClassDef(StPicoFwdTrack,2) - -}; - -#endif - From 46c65803d967694a806f9eadc0af01c62dbb1924 Mon Sep 17 00:00:00 2001 From: Daniel Brandenburg Date: Tue, 28 Jan 2025 20:52:15 -0500 Subject: [PATCH 05/10] Addressed comments from plexos/klendathu (only on 4 files this time) --- StRoot/StEvent/StFwdTrack.cxx | 9 ++---- StRoot/StEvent/StFwdTrack.h | 42 ++++++++++--------------- StRoot/StEvent/StFwdTrackCollection.cxx | 2 ++ StRoot/StEvent/StFwdTrackCollection.h | 4 +-- 4 files changed, 22 insertions(+), 35 deletions(-) diff --git a/StRoot/StEvent/StFwdTrack.cxx b/StRoot/StEvent/StFwdTrack.cxx index 1e9a3ef519f..2cbb5dca531 100644 --- a/StRoot/StEvent/StFwdTrack.cxx +++ b/StRoot/StEvent/StFwdTrack.cxx @@ -2,14 +2,9 @@ #include "StEvent/StFcsCluster.h" #include "St_base/StMessMgr.h" -StFwdTrack::StFwdTrack() { +StFwdTrack::StFwdTrack() {} -} - -StFwdTrack::~StFwdTrack() { - mEcalClusters.clear(); - mHcalClusters.clear(); -} +StFwdTrack::~StFwdTrack() {} /* momentum diff --git a/StRoot/StEvent/StFwdTrack.h b/StRoot/StEvent/StFwdTrack.h index f74ef75ed8e..c2fc0d1a62f 100644 --- a/StRoot/StEvent/StFwdTrack.h +++ b/StRoot/StEvent/StFwdTrack.h @@ -130,8 +130,7 @@ class StFwdTrack : public StObject { // Number of fit points used by GenFit short numberOfFitPoints() const; - // unsigned int numberOfPossibleFitPoints() const; - + // Number of points used in the track seed step short numberOfSeedPoints() const; UShort_t idTruth() const { return mIdTruth; } @@ -166,35 +165,28 @@ class StFwdTrack : public StObject { void addHcalCluster(StFcsCluster* p); void sortHcalClusterByET(); - protected: - - - // Track quality and convergence - bool mDidFitConverge; - bool mDidFitConvergeFully; - short mNumberOfFailedPoints; - short mNumberOfSeedPoints; - short mNumberOfFitPoints; - float mChi2; - float mNDF; - float mPval; - short mCharge; - StThreeVectorD mPrimaryMomentum; - StPtrVecFcsCluster mEcalClusters; - StPtrVecFcsCluster mHcalClusters; - /// MC track id - UShort_t mIdTruth; - /// MC track quality (percentage of hits coming from corresponding MC track) - UShort_t mQATruth; + bool mDidFitConverge; // did the fit converge + bool mDidFitConvergeFully; // did the fit converge fully (fwd and bkw) + short mNumberOfFailedPoints; // number of points that failed to converge + short mNumberOfSeedPoints; // number of points used in the seed step + short mNumberOfFitPoints; // number of points used in the fit (seed + vertex) + float mChi2; // chi2 of the fit + float mNDF; // number of degrees of freedom + float mPval; // p-value of the fit + short mCharge; // charge of the track + StThreeVectorD mPrimaryMomentum; // momentum at the primary vertex + StPtrVecFcsCluster mEcalClusters; // ECAL clusters + StPtrVecFcsCluster mHcalClusters; // HCAL clusters + + UShort_t mIdTruth; // MC track id + UShort_t mQATruth; // MC track quality (percentage of hits coming from corresponding MC track) float mDCA[3]; // DCA to the primary vertex UChar_t mVtxIndex; - - ClassDef(StFwdTrack,4) - + ClassDef(StFwdTrack,3) }; #endif diff --git a/StRoot/StEvent/StFwdTrackCollection.cxx b/StRoot/StEvent/StFwdTrackCollection.cxx index ca09d7130b8..9992078a408 100644 --- a/StRoot/StEvent/StFwdTrackCollection.cxx +++ b/StRoot/StEvent/StFwdTrackCollection.cxx @@ -15,6 +15,8 @@ ClassImp(StFwdTrackCollection) +StFwdTrackCollection::StFwdTrackCollection(){} + StFwdTrackCollection::~StFwdTrackCollection(){ for (unsigned int i=0; i Date: Tue, 28 Jan 2025 20:54:22 -0500 Subject: [PATCH 06/10] fix whitespace (tabs) --- StRoot/StEvent/StFwdTrackCollection.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/StRoot/StEvent/StFwdTrackCollection.cxx b/StRoot/StEvent/StFwdTrackCollection.cxx index 9992078a408..aa125352b31 100644 --- a/StRoot/StEvent/StFwdTrackCollection.cxx +++ b/StRoot/StEvent/StFwdTrackCollection.cxx @@ -19,9 +19,9 @@ StFwdTrackCollection::StFwdTrackCollection(){} StFwdTrackCollection::~StFwdTrackCollection(){ for (unsigned int i=0; i Date: Tue, 28 Jan 2025 20:55:06 -0500 Subject: [PATCH 07/10] fix whitespace (tabs) --- StRoot/StEvent/StFwdTrackCollection.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/StRoot/StEvent/StFwdTrackCollection.cxx b/StRoot/StEvent/StFwdTrackCollection.cxx index aa125352b31..6a33bb0002e 100644 --- a/StRoot/StEvent/StFwdTrackCollection.cxx +++ b/StRoot/StEvent/StFwdTrackCollection.cxx @@ -20,7 +20,7 @@ StFwdTrackCollection::StFwdTrackCollection(){} StFwdTrackCollection::~StFwdTrackCollection(){ for (unsigned int i=0; i Date: Tue, 28 Jan 2025 21:05:23 -0500 Subject: [PATCH 08/10] Pull in StFwdTrackMaker Changes from PR-571 --- StRoot/StFwdTrackMaker/StFwdQAMaker.cxx | 464 ++++- StRoot/StFwdTrackMaker/StFwdQAMaker.h | 35 + StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx | 1710 +++++++---------- StRoot/StFwdTrackMaker/StFwdTrackMaker.h | 259 +-- .../include/Tracker/FitterUtils.h | 144 ++ .../include/Tracker/FwdDataSource.h | 26 +- .../include/Tracker/FwdGeomUtils.h | 23 +- .../StFwdTrackMaker/include/Tracker/FwdHit.h | 50 +- .../include/Tracker/FwdTracker.h | 1684 +++++++++------- .../include/Tracker/ObjExporter.h | 74 +- .../include/Tracker/TrackFitter.h | 946 +++------ StRoot/StFwdTrackMaker/macro/build_geom.C | 5 +- StRoot/StFwdTrackMaker/macro/daq/daq_track.C | 69 +- StRoot/StFwdTrackMaker/macro/daq/submit.xml | 5 - StRoot/StFwdTrackMaker/macro/event/ana.C | 42 + StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C | 137 ++ StRoot/StFwdTrackMaker/macro/mudst/mudst.C | 130 ++ StRoot/StFwdTrackMaker/macro/mudst/pico.C | 602 ++++++ .../macro/mudst/submit_pico_run22pp.xml | 43 + StRoot/StFwdTrackMaker/macro/qa/mudst.C | 78 + StRoot/StFwdTrackMaker/macro/qa/qa.C | 281 +++ StRoot/StFwdTrackMaker/macro/sim/close.C | 108 ++ StRoot/StFwdTrackMaker/macro/sim/fast.C | 145 ++ StRoot/StFwdTrackMaker/macro/sim/gen.C | 87 +- StRoot/StFwdTrackMaker/macro/sim/jpsi.C | 225 +++ StRoot/StFwdTrackMaker/macro/sim/lambda.C | 191 ++ StRoot/StFwdTrackMaker/macro/sim/sim.C | 242 +++ .../macro/sim/single_particle_gun.C | 28 + StRoot/StFwdTrackMaker/macro/viz.C | 210 +- 29 files changed, 5298 insertions(+), 2745 deletions(-) create mode 100644 StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h create mode 100755 StRoot/StFwdTrackMaker/macro/event/ana.C create mode 100644 StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C create mode 100755 StRoot/StFwdTrackMaker/macro/mudst/mudst.C create mode 100755 StRoot/StFwdTrackMaker/macro/mudst/pico.C create mode 100644 StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml create mode 100755 StRoot/StFwdTrackMaker/macro/qa/mudst.C create mode 100755 StRoot/StFwdTrackMaker/macro/qa/qa.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/close.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/fast.C mode change 100644 => 100755 StRoot/StFwdTrackMaker/macro/sim/gen.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/jpsi.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/lambda.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/sim.C create mode 100755 StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C mode change 100644 => 100755 StRoot/StFwdTrackMaker/macro/viz.C diff --git a/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx b/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx index b7ce1cd225e..f356722b090 100644 --- a/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx +++ b/StRoot/StFwdTrackMaker/StFwdQAMaker.cxx @@ -36,8 +36,6 @@ #include "StMuDSTMaker/COMMON/StMuMcTrack.h" #include "StMuDSTMaker/COMMON/StMuFstHit.h" -// ClassImp(FcsClusterWithStarXYZ); - /** Clear the FwdQATreeData from one event to next */ void FwdQATreeData::clear(){ header.clear(); @@ -93,12 +91,12 @@ FcsHitWithStarXYZ::FcsHitWithStarXYZ( StMuFcsHit *hit, StFcsDb *fcsDb ) { } StFwdQAMaker::StFwdQAMaker() : StMaker("fwdQAMaker"), mTreeFile(nullptr), mTree(nullptr) { - + setLocalOutputFile( "./fwdHists.root" ); // default off } int StFwdQAMaker::Init() { - mTreeFile = new TFile("fwdtree.root", "RECREATE"); + mTreeFile = new TFile( mTreeFilename.Data(), "RECREATE"); mTree = new TTree("fwd", "fwd tracking tree"); mTree->Branch("header", &mTreeData. header, 3200, 99 ); @@ -107,7 +105,6 @@ int StFwdQAMaker::Init() { mTreeData.fstPoints.createBranch(mTree, "fstHits"); mTreeData.fttPoints.createBranch(mTree, "fttPoints"); mTreeData.fttClusters.createBranch(mTree, "fttClusters"); - mTreeData.fstPoints.createBranch(mTree, "fstPoints"); mTreeData.wcal.createBranch(mTree, "wcalClusters"); mTreeData.hcal.createBranch(mTree, "hcalClusters"); @@ -117,8 +114,63 @@ int StFwdQAMaker::Init() { mTreeData.reco.createBranch(mTree, "reco"); mTreeData.seeds.createBranch(mTree, "seeds"); + + + + //========================================================================================================= adding histograms (new) + AddHist( mHists["fwdMultFailed"] = new TH1F("fwdMultFailed", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultAll"] = new TH1F("fwdMultAll", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultGood"] = new TH1F("fwdMultGood", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultFST"] = new TH1F("fwdMultFST", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["nHitsFit"] = new TH1F("nHitsFit", ";nHitsFit; counts", 10, 0, 10) ); + AddHist( mHists["fwdMultEcalMatch"] = new TH1F("fwdMultEcalMatch", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultHcalMatch"] = new TH1F("fwdMultHcalMatch", ";N_{ch}^{FWD}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultEcalClusters"] = new TH1F("fwdMultEcalClusters", ";N_{Clu}^{ECAL}; counts", 100, 0, 100) ); + AddHist( mHists["fwdMultHcalClusters"] = new TH1F("fwdMultHcalClusters", ";N_{Clu}^{HCAL}; counts", 100, 0, 100) ); + AddHist( mHists["eta"] = new TH1F("eta", ";#eta; counts", 100, 0, 5) ); + AddHist( mHists["phi"] = new TH1F("phi", ";#phi; counts", 100, -3.1415926, 3.1415926) ); + AddHist( mHists["pt"] = new TH1F("pt", "; pT; counts", 500, 0, 10) ); + AddHist( mHists["charge"] = new TH1F("charge", "; charge; counts", 4, -2, 2) ); + AddHist( mHists["ecalMatchPerTrack"] = new TH1F("ecalMatchPerTrack", ";N_{match} / track; counts", 5, 0, 5) ); + AddHist( mHists["hcalMatchPerTrack"] = new TH1F("hcalMatchPerTrack", ";N_{match} / track; counts", 5, 0, 5) ); + AddHist( mHists["matchedEcalEnergy"] = new TH1F("matchedEcalEnergy", ";Energy; counts", 100, 0, 15) ); + AddHist( mHists["matchedHcalEnergy"] = new TH1F("matchedHcalEnergy", ";Energy; counts", 100, 0, 15) ); + AddHist( mHists["ecalEnergy"] = new TH1F("ecalEnergy", ";Energy; counts", 100, 0, 15) ); + AddHist( mHists["hcalEnergy"] = new TH1F("hcalEnergy", ";Energy; counts", 100, 0, 15) ); + AddHist( mHists["ecalXY"] = new TH2F( "ecalXY", ";ecalX;ecalY", 200, -200, 200, 200, -200, 200 ) ); + AddHist( mHists["hcalXY"] = new TH2F( "hcalXY", ";hcalX;hcalY", 200, 0, 50, 200, 0, 50 ) ); + AddHist( mHists["ecaldX"] = new TH1F( "ecaldX", ";dx (trk - ecal); counts", 400, -200, 200 ) ); + AddHist( mHists["matchedEcaldX"] = new TH1F( "matchedEcaldX", ";dx (trk - ecal); counts", 400, -200, 200 ) ); + AddHist( mHists["ecaldY"] = new TH1F( "ecaldY", ";dy (trk - ecal); counts", 400, -200, 200 ) ); + AddHist( mHists["matchedEcaldY"] = new TH1F( "matchedEcaldY", ";dy (trk - ecal); counts", 400, -200, 200 ) ); + AddHist( mHists["ecaldR"] = new TH1F( "ecaldR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); + AddHist( mHists["ecalMindR"] = new TH1F( "ecalMindR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); + AddHist( mHists["matchedEcaldR"] = new TH1F( "matchedEcaldR", ";dr (trk - ecal); counts", 400, 0, 400 ) ); + AddHist( mHists["hcaldX"] = new TH1F( "hcaldX", ";dx (trk - hcal); counts", 400, -200, 200 ) ); + AddHist( mHists["hcaldXdNFit"] = new TH2F( "hcaldXdNFit", ";dx (trk - hcal); nFit", 400, -200, 200, 10, 0, 10 ) ); + AddHist( mHists["matchedHcaldX"] = new TH1F( "matchedHcaldX", ";dx (trk - hcal); counts", 400, -200, 200 ) ); + AddHist( mHists["hcaldY"] = new TH1F( "hcaldY", ";dy (trk - hcal); counts", 400, -200, 200 ) ); + AddHist( mHists["hcaldYdNFit"] = new TH2F( "hcaldYdNFit", ";dy (trk - hcal); nFit", 400, -200, 200, 10, 0, 10 ) ); + AddHist( mHists["matchedHcaldY"] = new TH1F( "matchedHcaldY", ";dy (trk - hcal); counts", 400, -200, 200 ) ); + AddHist( mHists["hcaldR"] = new TH1F( "hcaldR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); + AddHist( mHists["hcalMindR"] = new TH1F( "hcalMindR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); + AddHist( mHists["matchedHcaldR"] = new TH1F( "matchedHcaldR", ";dr (trk - hcal); counts", 400, 0, 400 ) ); + AddHist( mHists["trkEcalX"] = new TH2F( "trkEcalX", ";trkX;ecalX", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkEcalY"] = new TH2F( "trkEcalY", ";trkY;ecalY", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkEcalMinX"] = new TH2F( "trkEcalMinX", ";trkX;ecalX", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkEcalMinY"] = new TH2F( "trkEcalMinY", ";trkY;ecalY", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkHcalX"] = new TH2F( "trkHcalX", ";trkX;hcalX", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkHcalY"] = new TH2F( "trkHcalY", ";trkY;hcalY", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkHcalMinX"] = new TH2F( "trkHcalMinX", ";trkX;hcalX", 300, -150, 150, 300, -150, 150 ) ); + AddHist( mHists["trkHcalMinY"] = new TH2F( "trkHcalMinY", ";trkY;hcalY", 300, -150, 150, 300, -150, 150 ) ); + +//=================================================================================================================================== + return kStOk; } + + + int StFwdQAMaker::Finish() { if ( mTreeFile && mTree ){ @@ -127,8 +179,29 @@ int StFwdQAMaker::Finish() { mTreeFile->Write(); LOG_DEBUG << "StFwdQA File written" << endm; } + + //beginning new + if ( mLocalOutputFile != "" ){ + auto prevDir = gDirectory; + + // output file name + TFile *fOutput = new TFile(mLocalOutputFile, "RECREATE"); + fOutput->cd(); + for (auto nh : mHists) { + nh.second->SetDirectory(gDirectory); + nh.second->Write(); + } + + // restore previous directory + gDirectory = prevDir; + + LOG_INFO << "Done writing StFwdQAMaker output to local file : " << mLocalOutputFile << endm; + }//end new + return kStOk; } + + int StFwdQAMaker::Make() { LOG_INFO << "FWD Report:" << endm; StEvent *mStEvent = static_cast(GetInputDS("StEvent")); @@ -136,46 +209,50 @@ int StFwdQAMaker::Make() { // report number of fwd tracks auto fwdTracks = mStEvent->fwdTrackCollection(); LOG_INFO << "Number of FwdTracks (StFwdTrackCollection): " << fwdTracks->tracks().size() << endm; - LOG_INFO << "Number of Ftt Points (StEvent)" << mStEvent->fttCollection()->points().size() << endm; + if ( mStEvent->fttCollection() ){ + LOG_INFO << "Number of Ftt Points (StEvent)" << mStEvent->fttCollection()->points().size() << endm; + } } LOG_INFO << "SETUP START" << endm; // setup the datasets / makers + + mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); if(mMuDstMaker) { mMuDst = mMuDstMaker->muDst(); mMuForwardTrackCollection = mMuDst->muFwdTrackCollection(); mMuFcsCollection = mMuDst->muFcsCollection(); + if (mMuDst->event()) + mTreeData.header.run = mMuDst->event()->runNumber(); if (mMuForwardTrackCollection){ LOG_DEBUG << "Number of StMuFwdTracks: " << mMuForwardTrackCollection->numberOfFwdTracks() << endm; } + else{ + LOG_DEBUG << "No muFwdTrackCollection " << endm; + } } else { LOG_DEBUG << "No StMuDstMaker found: " << mMuDstMaker << endm; } - mFcsDb = static_cast(GetDataSet("fcsDb")); + mFcsDb = static_cast(GetDataSet("fcsDb")); mFwdTrackMaker = (StFwdTrackMaker*) GetMaker( "fwdTrack" ); if (!mFwdTrackMaker) { LOG_WARN << "No StFwdTrackMaker found, skipping StFwdQAMaker" << endm; // return kStOk; } - mTreeData.header.run = mMuDst->event()->runNumber(); + LOG_DEBUG << "SETUP COMPLETE" << endm; + ProcessFwdTracks(); + ProcessFwdMuTracks(); - auto muFstCollection = mMuDst->muFstCollection(); - if ( muFstCollection ){ - LOG_DEBUG << "MuDst has #fst hits: " << muFstCollection->numberOfHits() << endm; - for ( size_t i = 0; i < muFstCollection->numberOfHits(); i++ ){ - StMuFstHit * h = muFstCollection->getHit(i); - mTreeData.fstPoints.add( h ); - } - } FillMcTracks(); - FillTracks(); - FillFstPoints(); + FillTracks(); //maybe not running + FillFstPoints(); //no fst FillFttClusters(); FillFcsStMuDst(); mTree->Fill(); + return kStOk; } void StFwdQAMaker::Clear(const Option_t *opts) { @@ -190,36 +267,10 @@ void StFwdQAMaker::FillFstPoints(){ return; } - // size_t numFwdHitsPrior = mFwdHitsFst.size(); LOG_INFO << "Loading " << fst->numberOfHits() << " StMuFstHits" << endm; - // TMatrixDSym hitCov3(3); for ( unsigned int index = 0; index < fst->numberOfHits(); index++){ StMuFstHit * muFstHit = fst->getHit( index ); mTreeData.fstPoints.add( muFstHit ); - - - // float vR = muFstHit->localPosition(0); - // float vPhi = muFstHit->localPosition(1); - // float vZ = muFstHit->localPosition(2); - - // const float dz0 = fabs( vZ - mFstZFromGeom[0] ); - // const float dz1 = fabs( vZ - mFstZFromGeom[1] ); - // const float dz2 = fabs( vZ - mFstZFromGeom[2] ); - // static const float fstThickness = 2.0; // thickness in cm between inner and outer on sigle plane - - // // assign disk according to which z value the hit has, within the z-plane thickness - // int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); - - // float x0 = vR * cos( vPhi ); - // float y0 = vR * sin( vPhi ); - // hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); - - // LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; - // mFstHits.push_back( TVector3( x0, y0, vZ) ); - - // // we use d+4 so that both FTT and FST start at 4 - // mFwdHitsFst.push_back(FwdHit(count++, x0, y0, vZ, d+4, 0, hitCov3, nullptr)); - // count++; } // index } @@ -244,6 +295,8 @@ void StFwdQAMaker::FillTracks() { break; } } + } else { + LOG_WARN << "No StMuFwdTrackCollection found" << endm; } LOG_DEBUG << "TRACKS COMPLETE" << endm; } @@ -273,7 +326,7 @@ void StFwdQAMaker::FillFcsStMuDst( ) { } else if ( clu->detectorId() == kFcsHcalNorthDetId || clu->detectorId() == kFcsHcalSouthDetId ){ LOG_INFO << "Adding HCAL Cluster to FwdTree" << endm; mTreeData.hcal.add( cluSTAR ); - } + } delete cluSTAR; } @@ -330,4 +383,325 @@ void StFwdQAMaker::FillFttClusters(){ mTreeData.fttPoints.add( c ); } } + else{ + LOG_INFO << "no muFttCollection " << endm; + } +} + +//==================================================adding new function + +void StFwdQAMaker::ProcessFwdTracks( ){ + // This is an example of how to process fwd track collection + LOG_DEBUG << "StFwdAnalysisMaker::ProcessFwdTracks" << endm; + StEvent *stEvent = static_cast(GetInputDS("StEvent")); + if (!stEvent) + return; + + if (stEvent){ + StFttCollection *fttCol = stEvent->fttCollection(); + if (fttCol){ + LOG_DEBUG << "The Ftt Collection has " << fttCol->numberOfPoints() << " points" << endm; + } + } + StFwdTrackCollection * ftc = stEvent->fwdTrackCollection(); + if (!ftc) { + LOG_DEBUG << "Forward Track Collection is not present" << endm; + return; + } + + LOG_DEBUG << "Checking FcsCollection" << endm; + StFcsCollection *fcs = stEvent->fcsCollection(); + if (!fcs) return; + + StFcsDb *mFcsDb = static_cast(GetDataSet("fcsDb")); + + size_t fwdMultEcalMatch = 0; + size_t fwdMultHcalMatch = 0; + size_t fwdMultFST = 0; + + LOG_INFO << "FwdTrackCollection has: " << ftc->tracks().size() << " tracks" << endm; + + getHist( "fwdMultAll" )->Fill( ftc->tracks().size() ); + + // Cluster info (independen t of tracks) + size_t fwdMultEcalClusters = 0; + size_t fwdMultHcalClusters = 0; + for ( int iDet = 0; iDet < 4; iDet++ ){ + for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ + StFcsCluster * clu = fcs->clusters(iDet)[i]; + + if ( iDet < 2 ){ + fwdMultEcalClusters++; + getHist( "ecalEnergy" )->Fill( clu->energy() ); + } else if ( iDet < 4 ){ + fwdMultHcalClusters++; + getHist( "hcalEnergy" )->Fill( clu->energy() ); + } + } + } + + getHist( "fwdMultEcalClusters" )->Fill( fwdMultEcalClusters ); + getHist( "fwdMultHcalClusters" )->Fill( fwdMultHcalClusters ); + + + size_t nGood = 0; + size_t nFailed = 0; + for ( auto fwdTrack : ftc->tracks() ){ + if ( !fwdTrack->didFitConvergeFully() ) { + nFailed++; + continue; + } + nGood++; + LOG_DEBUG << TString::Format("StFwdTrack[ nProjections=%lu, nFTTSeeds=%lu, nFSTSeeds=%lu, mPt=%f ]", fwdTrack->mProjections.size(), fwdTrack->mFTTPoints.size(), fwdTrack->mFSTPoints.size(), fwdTrack->momentum().perp()) << endm; + LOG_DEBUG << "track fit momentum " << TString::Format( "(pt=%f, eta=%f, phi=%f)", fwdTrack->momentum().perp(), fwdTrack->momentum().pseudoRapidity(), fwdTrack->momentum().phi() ) << endm; + LOG_DEBUG << "StFwdTrack has " << fwdTrack->ecalClusters().size() << " ecal matches" << endm; + LOG_DEBUG << "StFwdTrack has " << fwdTrack->hcalClusters().size() << " hcal matches" << endm; + + getHist("ecalMatchPerTrack")->Fill( fwdTrack->ecalClusters().size() ); + getHist("hcalMatchPerTrack")->Fill( fwdTrack->hcalClusters().size() ); + + getHist( "nHitsFit" )->Fill( fwdTrack->numberOfFitPoints() ); + + if (fwdTrack->mFSTPoints.size() > 0){ + fwdMultFST ++; + } + + getHist("eta")->Fill( fwdTrack->momentum().pseudoRapidity() ); + getHist("phi")->Fill( fwdTrack->momentum().phi() ); + getHist("pt")->Fill( fwdTrack->momentum().perp() ); + + getHist("charge")->Fill( fwdTrack->charge() ); + + // ecal proj + int detId = kFcsWcalId; + TVector3 ecalXYZ; + TVector3 ecapP; + + StFwdTrackProjection ecalProj = fwdTrack->getProjectionFor( detId, 0 ); + StFwdTrackProjection hcalProj = fwdTrack->getProjectionFor( kFcsHcalId, 0 ); + LOG_DEBUG << "EcalProj z= " << ecalProj.mXYZ.z() << endm; + LOG_DEBUG << "HcalProj z= " << hcalProj.mXYZ.z() << endm; + LOG_DEBUG << "EcalProj Mom" << TString::Format( "(pt=%f, eta=%f, phi=%f)", ecalProj.mMom.perp(), ecalProj.mMom.pseudoRapidity(), ecalProj.mMom.phi() ) << endm; + + for ( size_t iEcal = 0; iEcal < fwdTrack->ecalClusters().size(); iEcal++ ){ + StFcsCluster *clu = fwdTrack->ecalClusters()[iEcal]; + LOG_DEBUG << "Ecal clu detId = " << clu->detectorId() << endm; + getHist("matchedEcalEnergy")->Fill( clu->energy() ); + + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); + float dx = ecalProj.mXYZ.x() - xyz.x(); + float dy = ecalProj.mXYZ.y() - xyz.y(); + float dr = sqrt(dx*dx + dy*dy); + getHist("matchedEcaldX")->Fill( dx ); + getHist("matchedEcaldY")->Fill( dy ); + getHist("matchedEcaldR")->Fill( dr ); + } + + if (ecalProj.mXYZ.z() > 500){ + double mindR = 999; + StFcsCluster * cclu = nullptr; // closet cluster + for ( int iDet = 0; iDet < 2; iDet++ ){ + for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ + StFcsCluster * clu = fcs->clusters(iDet)[i]; + + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); + getHist("ecalXY")->Fill( xyz.x(), xyz.y() ); + + float dx = ecalProj.mXYZ.x() - xyz.x(); + float dy = ecalProj.mXYZ.y() - xyz.y(); + float dr = sqrt(dx*dx + dy*dy); + + if ( fabs(dy) < 25 ) + getHist( "ecaldX" )->Fill( dx ); + if ( fabs(dx) < 25 ) + getHist( "ecaldY" )->Fill( dy ); + getHist( "ecaldR" )->Fill( dr ); + if ( dr < mindR ){ + mindR = dr; + cclu = clu; + } + + getHist( "trkEcalX" ) -> Fill( ecalProj.mXYZ.x(), xyz.x() ); + getHist( "trkEcalY" ) -> Fill( ecalProj.mXYZ.y(), xyz.y() ); + + } + } + getHist( "ecalMindR" )->Fill( mindR ); + if (cclu){ + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(cclu->detectorId(), cclu->x(), cclu->y()); + getHist( "trkEcalMinX" ) -> Fill( ecalProj.mXYZ.x(), xyz.x() ); + getHist( "trkEcalMinY" ) -> Fill( ecalProj.mXYZ.y(), xyz.y() ); + } + } + + if (hcalProj.mXYZ.z() > 500){ + + double mindR = 999; + StFcsCluster * cclu = nullptr; + for ( int iDet = 2; iDet < 4; iDet++ ){ + for( size_t i = 0; i < fcs->clusters(iDet).size(); i++){ + StFcsCluster * clu = fcs->clusters(iDet)[i]; + if (!clu) continue; + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); + getHist("hcalXY")->Fill( xyz.x(), xyz.y() ); + + float dx = hcalProj.mXYZ.x() - xyz.x(); + float dy = hcalProj.mXYZ.y() - xyz.y(); + float dr = sqrt(dx*dx + dy*dy); + + if ( fabs(dy) < 25 ){ + getHist( "hcaldX" )->Fill( dx ); + getHist( "hcaldXdNFit" )->Fill( dx, fwdTrack->numberOfFitPoints() ); + + } + if ( fabs(dx) < 25 ){ + getHist( "hcaldY" )->Fill( dy ); + getHist( "hcaldYdNFit" )->Fill( dy, fwdTrack->numberOfFitPoints() ); + } + getHist( "hcaldR" )->Fill( dr ); + + if ( dr < mindR ){ + mindR = dr; + cclu = clu; + } + + getHist( "trkHcalX" ) -> Fill( hcalProj.mXYZ.x(), xyz.x() ); + getHist( "trkHcalY" ) -> Fill( hcalProj.mXYZ.y(), xyz.y() ); + } + } + getHist( "hcalMindR" )->Fill( mindR ); + if (cclu){ + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(cclu->detectorId(), cclu->x(), cclu->y()); + getHist( "trkHcalMinX" ) -> Fill( hcalProj.mXYZ.x(), xyz.x() ); + getHist( "trkHcalMinY" ) -> Fill( hcalProj.mXYZ.y(), xyz.y() ); + } + } + + if (fwdTrack->ecalClusters().size() > 0) + fwdMultEcalMatch++; + if (fwdTrack->hcalClusters().size() > 0) + fwdMultHcalMatch++; + + } // Loop ftc->tracks() + + getHist( "fwdMultGood" )->Fill( nGood ); + getHist( "fwdMultFailed" )->Fill( nFailed ); + getHist("fwdMultFST")->Fill( fwdMultFST ); + getHist("fwdMultHcalMatch")->Fill( fwdMultHcalMatch ); + getHist("fwdMultEcalMatch")->Fill( fwdMultEcalMatch ); + + LOG_INFO << "Found " << nFailed << " failed track fits out of " << ftc->tracks().size() << endm; +} // ProcessFwdTracks +//========================================================end of added function + + + +void StFwdQAMaker::ProcessFwdMuTracks( ){ + // This is an example of how to process fwd track collection + LOG_DEBUG << "StFwdAnalysisMaker::ProcessFwdMuTracks" << endm; + StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); + if(!mMuDstMaker) { + LOG_WARN << " No MuDstMaker ... bye-bye" << endm; + return; + } + StMuDst *mMuDst = mMuDstMaker->muDst(); + if(!mMuDst) { + LOG_WARN << " No MuDst ... bye-bye" << endm; + return; + } + StMuFwdTrackCollection * ftc = mMuDst->muFwdTrackCollection(); + if (!ftc) return; + + StMuFcsCollection *fcs = mMuDst->muFcsCollection(); + if (!fcs) return; + + LOG_INFO << "Number of StMuFwdTracks: " << ftc->numberOfFwdTracks() << endl; + + StFcsDb *mFcsDb = static_cast(GetDataSet("fcsDb")); + + size_t fwdMultFST = 0; + size_t fwdMultEcalMatch = 0; + size_t fwdMultHcalMatch = 0; + + for ( size_t iTrack = 0; iTrack < ftc->numberOfFwdTracks(); iTrack++ ){ + StMuFwdTrack * muFwdTrack = ftc->getFwdTrack( iTrack ); + // LOG_DEBUG << TString::Format("StMuFwdTrack[ nProjections=%lu, nFTTSeeds=%lu, nFSTSeeds=%lu, mPt=%f ]", muFwdTrack->mProjections.size(), muFwdTrack->mFTTPoints.size(), muFwdTrack->mFSTPoints.size(), muFwdTrack->momentum().Pt()) << endm; + + LOG_DEBUG << "StMuFwdTrack has " << muFwdTrack->mEcalClusters.GetEntries() << " Ecal matched" << endm; + LOG_DEBUG << "StMuFwdTrack has " << muFwdTrack->mHcalClusters.GetEntries() << " Hcal matched" << endm; + + getHist("eta")->Fill( muFwdTrack->momentum().Eta() ); + getHist("phi")->Fill( muFwdTrack->momentum().Phi() ); + + if (muFwdTrack->mFSTPoints.size() > 0){ + fwdMultFST ++; + } + + if (muFwdTrack->mEcalClusters.GetEntries() > 0) + fwdMultEcalMatch++; + if (muFwdTrack->mHcalClusters.GetEntries() > 0) + fwdMultHcalMatch++; + + + // ecal proj + int detId = kFcsWcalId; + TVector3 ecalXYZ; + TVector3 ecapP; + + StMuFwdTrackProjection ecalProj; + bool foundEcalProj = muFwdTrack->getProjectionFor( detId, ecalProj, 0 ); + + if (foundEcalProj){ + for( size_t i = 0; i < fcs->numberOfClusters(); i++){ + StMuFcsCluster * clu = fcs->getCluster(i); + + if ( clu->detectorId() > 1 ) continue; + + if ( clu->energy() < 1 ) continue; + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(clu->detectorId(), clu->x(), clu->y()); + + float dx = ecalProj.mXYZ.X() - xyz.x(); + float dy = ecalProj.mXYZ.Y() - xyz.y(); + float dr = sqrt(dx*dx + dy*dy); + + getHist( "ecaldX" )->Fill( dx ); + getHist( "ecaldY" )->Fill( dy ); + getHist( "ecaldR" )->Fill( dr ); + + getHist( "trkEcalX" ) -> Fill( ecalProj.mXYZ.X(), xyz.x() ); + + } // i + } // foundEcalProj + + + for ( int i = 0; i < muFwdTrack->mEcalClusters.GetEntries(); i++ ){ + auto c = (StMuFcsCluster*) muFwdTrack->mEcalClusters.At(i); + if (!c) continue; + getHist("ecalEnergy")->Fill( c->energy() ); + + LOG_DEBUG << "eCal Cluster detId = " << c->detectorId() << endm; + StThreeVectorD xyz = mFcsDb->getStarXYZfromColumnRow(c->detectorId(), c->x(), c->y()); + getHist("ecalXY")->Fill( xyz.x(), xyz.y() ); + + if (foundEcalProj){ + getHist("matchedEcaldX")->Fill( ecalProj.mXYZ.X() - xyz.x() ); + } + } // i + + getHist("ecalMatchPerTrack")->Fill( muFwdTrack->mEcalClusters.GetEntries() ); + getHist("hcalMatchPerTrack")->Fill( muFwdTrack->mHcalClusters.GetEntries() ); + + for ( int i = 0; i < muFwdTrack->mHcalClusters.GetEntries(); i++ ){ + auto c = (StMuFcsCluster*) muFwdTrack->mHcalClusters.At(i); + if (!c) continue; + getHist("hcalEnergy")->Fill( c->energy() ); + + getHist("hcalXY")->Fill( c->x(), c->y() ); + } // i + } // iTrack + + getHist("fwdMult")->Fill( ftc->numberOfFwdTracks() ); + getHist("fwdMultFST")->Fill( fwdMultFST ); + getHist("fwdMultHcalMatch")->Fill( fwdMultHcalMatch ); + getHist("fwdMultEcalMatch")->Fill( fwdMultEcalMatch ); } diff --git a/StRoot/StFwdTrackMaker/StFwdQAMaker.h b/StRoot/StFwdTrackMaker/StFwdQAMaker.h index bc60f98d5b4..b6f32db3724 100644 --- a/StRoot/StFwdTrackMaker/StFwdQAMaker.h +++ b/StRoot/StFwdTrackMaker/StFwdQAMaker.h @@ -15,6 +15,8 @@ #include "StEvent/StEnumerations.h" #include "StThreeVectorD.hh" +#include + class StMuFwdTrack; class StMuFwdTrackProjection; class ForwardTracker; @@ -198,6 +200,13 @@ class StFwdQAMaker : public StMaker { void FillTracks(); void FillMcTracks(); + void ProcessFwdTracks(); + void ProcessFwdMuTracks(); + + void setMuDstInput() { mAnalyzeMuDst = true; } + void setLocalOutputFile( TString f ) { mLocalOutputFile = f; } + void setTreeFilename( TString f ) {mTreeFilename = f;} + protected: TFile *mTreeFile = nullptr; TTree *mTree = nullptr; @@ -211,6 +220,32 @@ class StFwdQAMaker : public StMaker { StFwdTrackMaker *mFwdTrackMaker = nullptr; StFcsDb *mFcsDb = nullptr; + +//========================================================= new stuff + std::map mHists; + + /** + * @brief Get the Hist object from the map + * - Additional check and safety for missing histograms + * @param n Histogram name + * @return TH1* histogram if found, otherwise a 'nil' histogram with one bin + */ + TH1* getHist( TString n ){ + if (mHists.count(n)) + return mHists[n]; + LOG_ERROR << "Attempting to access non-existing histogram" << endm; + return new TH1F( "NULL", "NULL", 1, 0, 1 ); // returning nullptr can lead to seg fault, this fails softly + } + + /** + * @brief Control whether the analysis uses StEvent (default) or MuDst as input + * + */ + bool mAnalyzeMuDst = false; + TString mLocalOutputFile; + TString mTreeFilename; +//====================================================== end new stuff + }; diff --git a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx index a2881f3f660..4e1d6d39fa4 100644 --- a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx +++ b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx @@ -7,11 +7,10 @@ #include "KiTrack/IHit.h" #include "GenFit/Track.h" -#include "GenFit/GFRaveVertexFactory.h" #include "TMath.h" -#include +#include #include #include #include @@ -26,6 +25,8 @@ #include "StEvent/StRnDHit.h" #include "StEvent/StRnDHitCollection.h" #include "StEvent/StTrack.h" +#include "StEvent/StBTofCollection.h" +#include "StEvent/StBTofHeader.h" #include "StEvent/StTrackGeometry.h" #include "StEvent/StTrackNode.h" #include "StEvent/StPrimaryVertex.h" @@ -44,6 +45,9 @@ #include "StEventUtilities/StEventHelper.h" +#include "StMcEvent/StMcEvent.hh" +#include "StMcEvent/StMcVertex.hh" + #include "tables/St_g2t_fts_hit_Table.h" #include "tables/St_g2t_track_Table.h" #include "tables/St_g2t_vertex_Table.h" @@ -68,15 +72,16 @@ #include "StEvent/StFwdTrack.h" #include "GenFit/AbsMeasurement.h" +#include "StMuDSTMaker/COMMON/StMuDstMaker.h" +#include "StMuDSTMaker/COMMON/StMuDst.h" +#include "StMuDSTMaker/COMMON/StMuFstCollection.h" +#include "StMuDSTMaker/COMMON/StMuFstHit.h" +#include "StMuDSTMaker/COMMON/StMuPrimaryVertex.h" -FwdSystem* FwdSystem::sInstance = nullptr; -TMVA::Reader * BDTCrit2::reader = nullptr; -float BDTCrit2::Crit2_RZRatio = -999; -float BDTCrit2::Crit2_DeltaRho = -999; -float BDTCrit2::Crit2_DeltaPhi = -999; -float BDTCrit2::Crit2_StraightTrackRatio = -999; - +#include "sys/types.h" +#include "sys/sysinfo.h" +FwdSystem* FwdSystem::sInstance = nullptr; //_______________________________________________________________________________________ class GenfitUtils{ @@ -84,8 +89,6 @@ class GenfitUtils{ // For now, accept anything we are passed, no matter what it is or how bad it is template static bool accept( T ) { return true; } - - }; // GenfitUtils // Basic sanity cuts on genfit tracks @@ -112,10 +115,10 @@ template<> bool GenfitUtils::accept( genfit::Track *track ) } } - // Following line fails with an exception, because some tracks lack + // Following line fails with an exception, because some tracks lack // forward update, or prediction in fitter info at the first point // - // genfit::KalmanFitterInfo::getFittedState(bool) const of + // genfit::KalmanFitterInfo::getFittedState(bool) const of // GenFit/fitters/src/KalmanFitterInfo.cc:250 // Fitted state at the first point @@ -130,7 +133,7 @@ template<> bool GenfitUtils::accept( genfit::Track *track ) for ( ipoint = 0; ipoint < track->getNumPoints(); ipoint++ ) { first = track->getPointWithFitterInfo( ipoint ); if ( first ) break; - } + } // No points on the track have fit information if ( !first ) { @@ -158,7 +161,7 @@ class SiRasterizer { void setup(FwdTrackerConfig &_cfg) { cfg = _cfg; mRasterR = cfg.get("SiRasterizer:r", 3.0); - mRasterPhi = cfg.get("SiRasterizer:phi", 0.1); + mRasterPhi = cfg.get("SiRasterizer:phi", 0.004); } bool active() { @@ -191,13 +194,8 @@ class ForwardTracker : public ForwardTrackMaker { // Create the forward system... FwdSystem::sInstance = new FwdSystem(); - // make our quality plotter - mQualityPlotter = new QualityPlotter(mConfig); - mQualityPlotter->makeHistograms(mConfig.get("TrackFinder:nIterations", 1)); - // initialize the track fitter mTrackFitter = new TrackFitter(mConfig, geoCache); - mTrackFitter->setGenerateHistograms(genHistograms); mTrackFitter->setup(); ForwardTrackMaker::initialize( geoCache, genHistograms ); @@ -205,19 +203,10 @@ class ForwardTracker : public ForwardTrackMaker { void finish() { - if ( mGenHistograms ){ - mQualityPlotter->finish(); - writeEventHistograms(); - } - if (FwdSystem::sInstance){ delete FwdSystem::sInstance; FwdSystem::sInstance = 0; } - if (mQualityPlotter){ - delete mQualityPlotter; - mQualityPlotter = 0; - } if (mTrackFitter){ delete mTrackFitter; mTrackFitter= 0; @@ -226,8 +215,8 @@ class ForwardTracker : public ForwardTrackMaker { }; //________________________________________________________________________ -StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mGenHistograms(false), mGenTree(false), mForwardTracker(nullptr), mForwardData(nullptr){ - SetAttr("useFtt",1); // Default Ftt on +StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mForwardTracker(nullptr), mForwardData(nullptr), mGeoCache(""){ + SetAttr("useFtt",1); // Default Ftt on SetAttr("useFst",1); // Default Fst on SetAttr("useFcs",1); // Default Fcs on SetAttr("config", "config.xml"); // Default configuration file (user may override before Init()) @@ -235,39 +224,12 @@ StFwdTrackMaker::StFwdTrackMaker() : StMaker("fwdTrack"), mGenHistograms(false), }; int StFwdTrackMaker::Finish() { - - auto prevDir = gDirectory; - if ( mGenHistograms ) { - - // output file name - string name = mFwdConfig.get("Output:url", "fwdTrackerOutput.root"); - LOG_INFO << "Saving StFwdTrackMaker Histograms to ROOT file: " << name << endm; - TFile *fOutput = new TFile(name.c_str(), "RECREATE"); - fOutput->cd(); - - fOutput->mkdir("StFwdTrackMaker"); - fOutput->cd("StFwdTrackMaker"); - for (auto nh : mHistograms) { - nh.second->SetDirectory(gDirectory); - nh.second->Write(); - } - fOutput->cd(""); - } - mForwardTracker->finish(); - - prevDir->cd(); - - if (mGenTree) { - mTreeFile->cd(); - mTree->Write(); - mTreeFile->Write(); - } return kStOk; } void StFwdTrackMaker::LoadConfiguration() { - if (mConfigFile.length() < 5){ + if (mConfigFile.length() < 5){ LOG_INFO << "Forward Tracker is using default config for "; if ( defaultConfig == defaultConfigData ){ LOG_INFO << " DATA" << endm; @@ -284,226 +246,46 @@ void StFwdTrackMaker::LoadConfiguration() { //________________________________________________________________________ int StFwdTrackMaker::Init() { - if ( !configLoaded ){ LoadConfiguration(); } - if (mGenTree) { - mTreeFile = new TFile("fwdtree.root", "RECREATE"); - mTree = new TTree("fwd", "fwd tracking tree"); - mTree->Branch("fttN", &mTreeData. fttN, "fttN/I"); - mTree->Branch("fttX", &mTreeData. fttX ); - mTree->Branch("fttY", &mTreeData. fttY ); - mTree->Branch("fttZ", &mTreeData. fttZ ); - - mTree->Branch("fttTrackId", &mTreeData. fttTrackId ); - mTree->Branch("fttVolumeId", &mTreeData. fttVolumeId ); - mTree->Branch("fttPt", &mTreeData. fttPt ); - mTree->Branch("fttVertexId", &mTreeData. fttVertexId ); - - mTree->Branch("fstN", &mTreeData. fstN, "fstN/I"); - mTree->Branch("fstX", &mTreeData. fstX ); - mTree->Branch("fstY", &mTreeData. fstY ); - mTree->Branch("fstZ", &mTreeData. fstZ ); - mTree->Branch("fstTrackId", &mTreeData. fstTrackId ); - - mTree->Branch("fcsN", &mTreeData. fcsN, "fcsN/I"); - mTree->Branch("fcsX", &mTreeData. fcsX ); - mTree->Branch("fcsY", &mTreeData. fcsY ); - mTree->Branch("fcsZ", &mTreeData. fcsZ ); - mTree->Branch("fcsDet", &mTreeData. fcsDet ); - - // mc tracks - mTree->Branch("mcN", &mTreeData. mcN, "mcN/I"); - mTree->Branch("mcPt", &mTreeData. mcPt ); - mTree->Branch("mcEta", &mTreeData. mcEta ); - mTree->Branch("mcPhi", &mTreeData. mcPhi ); - mTree->Branch("mcCharge", &mTreeData. mcCharge ); - mTree->Branch("mcVertexId", &mTreeData. mcVertexId ); - - // mcverts - mTree->Branch("vmcN", &mTreeData. vmcN, "vmcN/I"); - mTree->Branch("vmcX", &mTreeData. vmcX ); - mTree->Branch("vmcY", &mTreeData. vmcY ); - mTree->Branch("vmcZ", &mTreeData. vmcZ ); - - // rcverts - mTree->Branch("vrcN", &mTreeData. vrcN, "vrcN/I"); - mTree->Branch("vrcX", &mTreeData. vrcX ); - mTree->Branch("vrcY", &mTreeData. vrcY ); - mTree->Branch("vrcZ", &mTreeData. vrcZ ); - - // rc tracks - mTree->Branch("rcN", &mTreeData. rcN, "rcN/I"); - mTree->Branch("rcPt", &mTreeData. rcPt ); - mTree->Branch("rcEta", &mTreeData. rcEta ); - mTree->Branch("rcPhi", &mTreeData. rcPhi ); - mTree->Branch("rcCharge", &mTreeData. rcCharge ); - mTree->Branch("rcTrackId", &mTreeData. rcTrackId ); - mTree->Branch("rcNumFST", &mTreeData. rcNumFST ); - mTree->Branch("rcNumFTT", &mTreeData. rcNumFTT ); - mTree->Branch("rcNumPV", &mTreeData. rcNumPV ); - mTree->Branch("rcQuality", &mTreeData. rcQuality ); - - mTree->Branch("thdN", &mTreeData. thdN, "thdN/I"); - mTree->Branch("thdX", &mTreeData. thdX ); - mTree->Branch("thdY", &mTreeData. thdY ); - mTree->Branch("thaX", &mTreeData. thaX ); - mTree->Branch("thaY", &mTreeData. thaY ); - mTree->Branch("thaZ", &mTreeData. thaZ ); - - // track projections - mTree->Branch("tprojN", &mTreeData. tprojN, "tprojN/I"); - mTree->Branch("tprojIdD", &mTreeData. tprojIdD); - mTree->Branch("tprojIdT", &mTreeData. tprojIdT); - mTree->Branch("tprojX", &mTreeData. tprojX); - mTree->Branch("tprojY", &mTreeData. tprojY); - mTree->Branch("tprojZ", &mTreeData. tprojZ); - mTree->Branch("tprojPx", &mTreeData. tprojPx); - mTree->Branch("tprojPy", &mTreeData. tprojPy); - mTree->Branch("tprojPz", &mTreeData. tprojPz); - - std::string path = "TrackFinder.Iteration[0].SegmentBuilder"; - std::vector paths = mFwdConfig.childrenOf(path); - - if (mTreeData.saveCrit){ - for (string p : paths) { - string name = mFwdConfig.get(p + ":name", ""); - mTreeData.Crits[name]; // create the entry - mTree->Branch(name.c_str(), &mTreeData.Crits[name]); - mTree->Branch((name + "_trackIds").c_str(), &mTreeData.CritTrackIds[name]); - - if ( name == "Crit2_RZRatio" ){ - string n = name + "_x1"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_y1"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_z1"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_x2"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_y2"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_z2"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - - n = name + "_h1"; - mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); - n = name + "_h2"; - mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); - n = name + "_h3"; - mTreeData.CritTrackIds[(n)]; mTree->Branch(n.c_str(), &mTreeData.CritTrackIds[n]); - } - - if ( name == "Crit2_BDT" ){ - string n = name + "_DeltaPhi"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - n = name + "_DeltaRho"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - n = name + "_RZRatio"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - n = name + "_StraightTrackRatio"; - mTreeData.Crits[(n)]; mTree->Branch(n.c_str(), &mTreeData.Crits[n]); - } - } - - // Three hit criteria - path = "TrackFinder.Iteration[0].ThreeHitSegments"; - paths = mFwdConfig.childrenOf(path); - - for (string p : paths) { - string name = mFwdConfig.get(p + ":name", ""); - mTreeData.Crits[name]; // create the entry - mTree->Branch(name.c_str(), &mTreeData.Crits[name]); - mTree->Branch((name + "_trackIds").c_str(), &mTreeData.CritTrackIds[name]); - } - } - - mTree->SetAutoFlush(0); - } // gen tree - - - /// Instantiate and cache the geometry - GetDataBase("VmcGeometry"); + if ( mGeoCache == "" ){ + /// Instantiate and cache the geometry + GetDataBase("VmcGeometry"); + mGeoCache = GetChainOpt()->GetFileOut(); + if ( mGeoCache=="" ) + mGeoCache = GetChainOpt()->GetFileIn(); - - TString geoCache = GetChainOpt()->GetFileOut(); - if ( geoCache=="" ) - geoCache = GetChainOpt()->GetFileIn(); - - // Strip out @ symbol - geoCache = geoCache.ReplaceAll("@",""); - // Strip off the last extention in the geoCache - geoCache = geoCache( 0, geoCache.Last('.') ); - // Append geom.root to the extentionless geoCache - geoCache+=".geom.root"; - - // create an SiRasterizer in case we need it + // Strip out @ symbol + mGeoCache = mGeoCache.ReplaceAll("@",""); + // Strip off the last extention in the mGeoCache + mGeoCache = mGeoCache( 0, mGeoCache.Last('.') ); + // Append geom.root to the extentionless mGeoCache + mGeoCache+=".geom.root"; + } + // create an SiRasterizer in case we need it mSiRasterizer = std::shared_ptr( new SiRasterizer(mFwdConfig)); mForwardTracker = std::shared_ptr(new ForwardTracker( )); mForwardTracker->setConfig(mFwdConfig); - // only save criteria values if we are generating a tree. - mForwardTracker->setSaveCriteriaValues(mGenTree); + // in production we disable crit saving. + mForwardTracker->setSaveCriteriaValues(false); mForwardData = std::shared_ptr(new FwdDataSource()); mForwardTracker->setData(mForwardData); - mForwardTracker->initialize( geoCache, mGenHistograms ); - - if ( mGenHistograms ){ - mHistograms["fwdVertexZ"] = new TH1D("fwdVertexZ", "FWD Vertex (RAVE);z", 1000, -50, 50); - mHistograms["fwdVertexXY"] = new TH2D("fwdVertexXY", "FWD Vertex (RAVE);x;y", 100, -1, 1, 100, -1, 1); - mHistograms["fwdVertexDeltaZ"] = new TH2D("fwdVertexDeltaZ", "FWD Vertex - MC Vertex;#Delta z", 100, -1, 1, 100, -1, 1); - - mHistograms["McEventEta"] = new TH1D("McEventEta", ";MC Track Eta", 1000, -5, 5); - mHistograms["McEventPt"] = new TH1D("McEventPt", ";MC Track Pt (GeV/c)", 1000, 0, 10); - mHistograms["McEventPhi"] = new TH1D("McEventPhi", ";MC Track Phi", 1000, 0, 6.2831852); - - // these are tracks within 2.5 < eta < 4.0 - mHistograms["McEventFwdEta"] = new TH1D("McEventFwdEta", ";MC Track Eta", 1000, -5, 5); - mHistograms["McEventFwdPt"] = new TH1D("McEventFwdPt", ";MC Track Pt (GeV/c)", 1000, 0, 10); - mHistograms["McEventFwdPhi"] = new TH1D("McEventFwdPhi", ";MC Track Phi", 1000, 0, 6.2831852); + mForwardTracker->initialize( mGeoCache, false ); - // create mHistograms - mHistograms["nMcTracks"] = new TH1I("nMcTracks", ";# MC Tracks/Event", 1000, 0, 1000); - mHistograms["nMcTracksFwd"] = new TH1I("nMcTracksFwd", ";# MC Tracks/Event", 1000, 0, 1000); - mHistograms["nMcTracksFwdNoThreshold"] = new TH1I("nMcTracksFwdNoThreshold", ";# MC Tracks/Event", 1000, 0, 1000); - - mHistograms["nHitsSTGC"] = new TH1I("nHitsSTGC", ";# STGC Hits/Event", 1000, 0, 1000); - mHistograms["nHitsFSI"] = new TH1I("nHitsFSI", ";# FSIT Hits/Event", 1000, 0, 1000); - - mHistograms["stgc_volume_id"] = new TH1I("stgc_volume_id", ";stgc_volume_id", 50, 0, 50); - mHistograms["fsi_volume_id"] = new TH1I("fsi_volume_id", ";fsi_volume_id", 50, 0, 50); - - mHistograms["fsiHitDeltaR"] = new TH1F("fsiHitDeltaR", "FSI; delta r (cm); ", 500, -5, 5); - mHistograms["fsiHitDeltaPhi"] = new TH1F("fsiHitDeltaPhi", "FSI; delta phi; ", 500, -5, 5); - - // there are 4 stgc stations - for (int i = 0; i < 4; i++) { - mHistograms[TString::Format("stgc%dHitMap", i).Data()] = new TH2F(TString::Format("stgc%dHitMap", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - - mHistograms[TString::Format("stgc%dHitMapPrim", i).Data()] = new TH2F(TString::Format("stgc%dHitMapPrim", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - mHistograms[TString::Format("stgc%dHitMapSec", i).Data()] = new TH2F(TString::Format("stgc%dHitMapSec", i), TString::Format("STGC Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - } - - // There are 3 silicon stations - for (int i = 0; i < 3; i++) { - mHistograms[TString::Format("fsi%dHitMap", i).Data()] = new TH2F(TString::Format("fsi%dHitMap", i), TString::Format("FSI Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - mHistograms[TString::Format("fsi%dHitMapZ", i).Data()] = new TH2F(TString::Format("fsi%dHitMapZ", i), TString::Format("FSI Layer %d; x (cm); y(cm)", i), 200, -100, 100, 200, -100, 100); - - mHistograms[TString::Format("fsi%dHitMapR", i).Data()] = new TH1F(TString::Format("fsi%dHitMapR", i), TString::Format("FSI Layer %d; r (cm); ", i), 500, 0, 50); - mHistograms[TString::Format("fsi%dHitMapPhi", i).Data()] = new TH1F(TString::Format("fsi%dHitMapPhi", i), TString::Format("FSI Layer %d; phi; ", i), 320, 0, TMath::Pi() * 2 + 0.1); - } - - } // mGenHistograms - LOG_DEBUG << "StFwdTrackMaker::Init" << endm; + // geometry should be available from here (mForwardTracker will initialize cache if needed) + if (gGeoManager) { + FwdGeomUtils fwdGeoUtils( gGeoManager ); + // get the z-locations from geometry model and fallback to the defaults + auto fstZ = fwdGeoUtils.fstZ( {151.750000, 165.248001, 178.781006} ); + mFstZFromGeom.assign( fstZ.begin(), fstZ.end() ); + auto fttZ = fwdGeoUtils.fttZ( {280.904999, 303.704987, 326.605011, 349.404999} ); + mFttZFromGeom.assign( fttZ.begin(), fttZ.end() ); + } return kStOK; }; @@ -570,68 +352,84 @@ void StFwdTrackMaker::loadFttHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdD StEvent *event = (StEvent *)GetDataSet("StEvent"); string fttFromSource = mFwdConfig.get( "Source:ftt", "" ); - if (!event){ + if (!event){ LOG_ERROR << "No StEvent, cannot load Ftt Data" << endm; return; } - // Load GEANT hits directly if requested - if ( "GEANT" == fttFromSource ) { - LOG_DEBUG << "Loading sTGC hits directly from GEANT hits" << endm; - loadFttHitsFromGEANT( mcTrackMap, hitMap, count ); - return; - } - StFttCollection *col = event->fttCollection(); // From Data if ( col || "DATA" == fttFromSource ) { loadFttHitsFromStEvent( mcTrackMap, hitMap, count ); return; } + + // Load GEANT hits directly if requested + if ( true ) { + LOG_DEBUG << "Try loading sTGC hits directly from GEANT hits" << endm; + loadFttHitsFromGEANT( mcTrackMap, hitMap, count ); + return; + } } // loadFttHits void StFwdTrackMaker::loadFttHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ LOG_DEBUG << "Loading FTT Hits from Data" << endm; StEvent *event = (StEvent *)GetDataSet("StEvent"); StFttCollection *col = event->fttCollection(); - - mTreeData.fttN = 0; + size_t numFwdHitsPrior = mFwdHitsFtt.size(); if ( col && col->numberOfPoints() > 0 ){ LOG_DEBUG << "The Ftt Collection has " << col->numberOfPoints() << " points" << endm; TMatrixDSym hitCov3(3); - const double sigXY = 0.2; // + const double sigXY = 0.2; // hitCov3(0, 0) = sigXY * sigXY; hitCov3(1, 1) = sigXY * sigXY; hitCov3(2, 2) = 4; // unused since they are loaded as points on plane + static const double mm_to_cm = 0.1; for ( auto point : col->points() ){ - - FwdHit *hit = new FwdHit(count++, point->xyz().x()/10.0, point->xyz().y()/10.0, point->xyz().z(), -point->plane(), 0, hitCov3, nullptr); - mFttHits.push_back( TVector3( point->xyz().x()/10.0, point->xyz().y()/10.0, point->xyz().z() ) ); - if ( mGenHistograms ) { - mHistograms[TString::Format("stgc%dHitMapSec", point->plane()).Data()]->Fill(point->xyz().x()/10.0, point->xyz().y()/10.0); - } - // Add the hit to the hit map - hitMap[hit->getSector()].push_back(hit); - if (mGenTree && (unsigned)mTreeData.fttN < MAX_TREE_ELEMENTS) { - LOG_DEBUG << "FttPoint( " << TString::Format( "[plane=%d, quad=%d, nClu=%d]", point->plane(), point->quadrant(), point->nClusters() ) << point->xyz().x()/10.0 << ", " << point->xyz().y()/10.0 << ", " << point->xyz().z() << " )" << endm; - mTreeData.fttX.push_back( point->xyz().x()/10.0 ); - mTreeData.fttY.push_back( point->xyz().y()/10.0 ); - mTreeData.fttZ.push_back( point->xyz().z() ); - mTreeData.fttTrackId.push_back( 0 ); - mTreeData.fttVolumeId.push_back( point->plane() ); - mTreeData.fttPt.push_back( 0 ); - mTreeData.fttVertexId.push_back( 0 ); - mTreeData.fttN++; + float xcm = point->xyz().x()*mm_to_cm; + float ycm = point->xyz().y()*mm_to_cm; + float zcm = point->xyz().z(); + + // get the track id + int track_id = point->idTruth(); + shared_ptr mcTrack = nullptr; + if ( mcTrackMap.count(track_id) ) { + mcTrack = mcTrackMap[track_id]; + LOG_DEBUG << "Adding McTrack to FTT hit: " << track_id << endm; } - } - return; + mFwdHitsFtt.push_back(FwdHit(count++, // id + xcm, ycm, zcm, + -point->plane(), // volume id + kFttId, // detid + track_id, // track id + hitCov3, // covariance matrix + mcTrack) // mcTrack + ); + mFttHits.push_back( TVector3( xcm, ycm, zcm) ); + } // end of loop over points } else { LOG_DEBUG << "The Ftt Collection is EMPTY points" << endm; } - LOG_DEBUG << "Number of FTT in TTree: " << mTreeData.fttN << endm; + + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFtt.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFtt[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + // add to MC track map + if ( hit->getMcTrack() ){ + hit->getMcTrack()->addFttHit(hit); + } + } + + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FTT hits from StEvent" << endm; + } } void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ @@ -639,27 +437,22 @@ void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrack // STGC Hits St_g2t_fts_hit *g2t_stg_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_stg_hit"); - - mTreeData.fttN = 0; + size_t numFwdHitsPrior = mFwdHitsFtt.size(); if (!g2t_stg_hits){ - LOG_WARN << "geant/g2t_stg_hit is empty" << endm; + LOG_WARN << "geant/g2t_stg_hit is empty" << endm; return; } // make the Covariance Matrix once and then reuse TMatrixDSym hitCov3(3); - const double sigXY = 0.01; + const double sigXY = 0.02; hitCov3(0, 0) = sigXY * sigXY; hitCov3(1, 1) = sigXY * sigXY; - hitCov3(2, 2) = 1.0; // unused since they are loaded as points on plane + hitCov3(2, 2) = 0.1; // unused since they are loaded as points on plane int nstg = g2t_stg_hits->GetNRows(); LOG_DEBUG << "This event has " << nstg << " stg hits in geant/g2t_stg_hit " << endm; - if ( mGenHistograms ) { - mHistograms["nHitsSTGC"]->Fill(nstg); - } - bool filterGEANT = mFwdConfig.get( "Source:fttFilter", false ); for (int i = 0; i < nstg; i++) { @@ -675,152 +468,258 @@ void StFwdTrackMaker::loadFttHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrack if ( volume_id % 2 ==0 ) continue; - float x = git->x[0] + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso - float y = git->x[1] + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso + float x = git->x[0];// + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso + float y = git->x[1];// + gRandom->Gaus(0, sigXY); // 100 micron blur according to approx sTGC reso float z = git->x[2]; - - - if (mGenTree && (unsigned)mTreeData.fttN < MAX_TREE_ELEMENTS) { - mTreeData.fttX.push_back( x ); - mTreeData.fttY.push_back( y ); - mTreeData.fttZ.push_back( z ); - mTreeData.fttTrackId.push_back( track_id ); - mTreeData.fttVolumeId.push_back( plane_id ); - mTreeData.fttPt.push_back( mcTrackMap[track_id]->mPt ); - mTreeData.fttVertexId.push_back( mcTrackMap[track_id]->mStartVertex ); - mTreeData.fttN++; - } else if ( mGenTree ){ - LOG_WARN << "Truncating hits in TTree output" << endm; + if (plane_id < 0 || plane_id >= 4) { + continue; } + mFwdHitsFtt.push_back( + FwdHit( + count++, // id + x, y, z, // position + -plane_id, // volume id + kFttId, // detid + track_id, // track id + hitCov3, // covariance matrix + mcTrackMap[track_id] // mcTrack + ) + ); + mFttHits.push_back( TVector3( x, y, z ) ); + } // loop on hits - if ( mGenHistograms ){ - mHistograms["stgc_volume_id"]->Fill(volume_id); - } + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFtt.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFtt[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); - if (plane_id < 4 && plane_id >= 0) { - if ( mGenHistograms ){ - mHistograms[TString::Format("stgc%dHitMap", plane_id).Data()]->Fill(x, y); - } - } else { - continue; + if ( dynamic_cast(hit)->_mcTrack ){ + dynamic_cast(hit)->_mcTrack->addFttHit(hit); } + } - // this rejects GEANT hits with eta -999 - do we understand this effect? - if ( filterGEANT ) { - if ( mcTrackMap[track_id] && fabs(mcTrackMap[track_id]->mEta) > 5.0 ){ - - if ( mGenHistograms ) - mHistograms[TString::Format("stgc%dHitMapSec", plane_id).Data()]->Fill(x, y); - continue; - } else if ( mcTrackMap[track_id] && fabs(mcTrackMap[track_id]->mEta) < 5.0 ){ - if ( mGenHistograms ) mHistograms[TString::Format("stgc%dHitMapPrim", plane_id).Data()]->Fill(x, y); - } - } + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from MuDst" << endm; + } - FwdHit *hit = new FwdHit(count++, x, y, z, -plane_id, track_id, hitCov3, mcTrackMap[track_id]); +} // loadFttHits - // Add the hit to the hit map - hitMap[hit->getSector()].push_back(hit); - mFttHits.push_back( TVector3( x, y, z ) ); +/** + * @brief Loads FST hits from various sources into the hitmap and McTrackMap (if availabale) + * + * Order of precedence: + * MuDst StMuFstCollection (Data) + * StEvent StFstHitCollection (Data or slowsim) + * StEvent StRndHitCollection (fast sim) + * GEANT St_g2t_fts_hit (starsim only) - note if rasterizer is active this takes priority over FastSim + * + * @param mcTrackMap : MC track map if running sim + * @param hitMap : FST hitmap to populate + * @param count : number of hits loaded + */ +int StFwdTrackMaker::loadFstHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap ){ + + int count = loadFstHitsFromMuDst(mcTrackMap, hitMap); + if ( count > 0 ) return count; // only load from one source at a time + + count += loadFstHitsFromStEvent(mcTrackMap, hitMap); + if ( count > 0 ) return count; // only load from one source at a time - // Add hit pointer to the track - if (mcTrackMap[track_id]){ - mcTrackMap[track_id]->addHit(hit); - } else { - LOG_ERROR << "Cannot find MC track for GEANT hit (FTT), track_id = " << track_id << endm; - } - } // loop on hits + bool siRasterizer = mFwdConfig.get( "SiRasterizer:active", false ); + + if ( !siRasterizer ) count += loadFstHitsFromStRnDHits( mcTrackMap, hitMap ); + if ( count > 0 ) return count; // only load from one source at a time + + return loadFstHitsFromGEANT( mcTrackMap, hitMap ); +} // loadFstHits + +int StFwdTrackMaker::loadFstHitsFromMuDst( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ + int count = 0; + StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); + if(!mMuDstMaker) { + LOG_WARN << " No MuDstMaker ... bye-bye" << endm; + return 0; + } + StMuDst *mMuDst = mMuDstMaker->muDst(); + if(!mMuDst) { + LOG_WARN << " No MuDst ... bye-bye" << endm; + return 0; + } - if (mGenTree){ - LOG_INFO << "Saving " << mTreeData.fttN << " hits in Tree" << endm; + StMuFstCollection * fst = mMuDst->muFstCollection(); + if (!fst) { + LOG_WARN << "No StMuFstCollection ... bye-bye" << endm; + return 0; } -} // loadFttHits -void StFwdTrackMaker::loadFstHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ + size_t numFwdHitsPrior = mFwdHitsFst.size(); + LOG_INFO << "Loading " << fst->numberOfHits() << " StMuFstHits" << endm; + TMatrixDSym hitCov3(3); + for ( unsigned int index = 0; index < fst->numberOfHits(); index++){ + StMuFstHit * muFstHit = fst->getHit( index ); + + float vR = muFstHit->localPosition(0); + float vPhi = muFstHit->localPosition(1); + float vZ = muFstHit->localPosition(2); + + const float dz0 = fabs( vZ - mFstZFromGeom[0] ); + const float dz1 = fabs( vZ - mFstZFromGeom[1] ); + const float dz2 = fabs( vZ - mFstZFromGeom[2] ); + static const float fstThickness = 2.0; // thickness in cm between inner and outer on sigle plane + + // assign disk according to which z value the hit has, within the z-plane thickness + int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); + + float x0 = vR * cos( vPhi ); + float y0 = vR * sin( vPhi ); + hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); + + LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; + mFstHits.push_back( TVector3( x0, y0, vZ) ); + + // we use d+4 so that both FTT and FST start at 4 + mFwdHitsFst.push_back( + FwdHit( + count++, // id + x0, y0, vZ, // position + d+4, // volume id + kFstId, // detid + 0, // track id + hitCov3, // covariance matrix + nullptr // mcTrack + ) + ); + } // index + + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFst.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + } + + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from MuDst" << endm; + } + + // TODO add to hitmap + return count; +} // loadFstHitsFromMuDst + +int StFwdTrackMaker::loadFstHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ + int count = 0; StEvent *event = (StEvent *)GetDataSet("StEvent"); + if (!event) { + LOG_WARN << "No StEvent, cannot load FST hits from StEvent StFstHitCollection" << endm; + return 0; + } + LOG_DEBUG << "Got StEvent, loading Fst Hits" << endm; StFstHitCollection *fstHitCollection = event->fstHitCollection(); + size_t numFwdHitsPrior = mFwdHitsFst.size(); - if ( fstHitCollection ){ + if ( fstHitCollection && fstHitCollection->numberOfHits() > 0){ // reuse this to store cov mat TMatrixDSym hitCov3(3); LOG_DEBUG << "StFstHitCollection is NOT NULL, loading hits" << endm; for ( unsigned int iw = 0; iw < kFstNumWedges; iw++ ){ StFstWedgeHitCollection * wc = fstHitCollection->wedge( iw ); - + if ( !wc ) continue; for ( unsigned int is = 0; is < kFstNumSensorsPerWedge; is++ ){ StFstSensorHitCollection * sc = wc->sensor( is ); - + if ( !sc ) continue; StSPtrVecFstHit fsthits = sc->hits(); - mTreeData.fstN = 0; for ( unsigned int ih = 0; ih < fsthits.size(); ih++ ){ float vR = fsthits[ih]->localPosition(0); float vPhi = fsthits[ih]->localPosition(1); float vZ = fsthits[ih]->localPosition(2); - const float dz0 = fabs( vZ - 151.75 ); - const float dz1 = fabs( vZ - 165.248 ); - const float dz2 = fabs( vZ - 178.781 ); - - int d = 0 * ( dz0 < 1.0 ) + 1 * ( dz1 < 1.0 ) + 2 * ( dz2 < 1.0 ); - + const float dz0 = fabs( vZ - mFstZFromGeom[0] ); + const float dz1 = fabs( vZ - mFstZFromGeom[1] ); + const float dz2 = fabs( vZ - mFstZFromGeom[2] ); + static const float fstThickness = 3.0; // thickness in cm between inner and outer on sigle plane + // assign disk according to which z value the hit has, within the z-plane thickness + int d = 0 * ( dz0 < fstThickness ) + 1 * ( dz1 < fstThickness ) + 2 * ( dz2 < fstThickness ); float x0 = vR * cos( vPhi ); float y0 = vR * sin( vPhi ); hitCov3 = makeSiCovMat( TVector3( x0, y0, vZ ), mFwdConfig ); - LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; + LOG_DEBUG << "FST HIT: d = " << d << ", x=" << x0 << ", y=" << y0 << ", z=" << vZ << endm; mFstHits.push_back( TVector3( x0, y0, vZ) ); + int track_id = fsthits[ih]->idTruth(); + LOG_DEBUG << "FST Hit: idTruth = " << track_id << endm; + shared_ptr mcTrack = nullptr; + if ( mcTrackMap.count(track_id) ) { + mcTrack = mcTrackMap[track_id]; + LOG_DEBUG << "Adding McTrack to FST hit" << endm; + } - FwdHit *hit = new FwdHit(count++, x0, y0, vZ, d, 0, hitCov3, nullptr); - // Add the hit to the hit map - hitMap[hit->getSector()].push_back(hit); - - mTreeData.fstX.push_back( x0 ); - mTreeData.fstY.push_back( y0 ); - mTreeData.fstZ.push_back( vZ ); - - mTreeData.fstN++; + // we use d+4 so that both FTT and FST start at 4 + mFwdHitsFst.push_back( + FwdHit( + count++, // id + x0, y0, vZ, // position + d+4, // volume id + kFstId, // detid + track_id, // mc track id + hitCov3, // covariance matrix + mcTrack // mcTrack + ) + ); + // store a pointer to the original StFstHit + mFwdHitsFst.back()._hit = fsthits[ih]; } } // loop is } // loop iw - LOG_DEBUG << " FOUND " << mFstHits.size() << " FST HITS" << endm; - return; + LOG_DEBUG << " FOUND " << mFstHits.size() << " FST HITS in StFstHitCollection" << endm; } // fstHitCollection - - StRnDHitCollection *rndCollection = nullptr; - if (nullptr != event) { - rndCollection = event->rndHitCollection(); + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFst.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + // add to MC track map + if ( hit->getMcTrack() ){ + hit->getMcTrack()->addFstHit(hit); + } } - bool siRasterizer = mFwdConfig.get( "SiRasterizer:active", false ); - if ( siRasterizer || rndCollection == nullptr ){ - LOG_DEBUG << "Loading Fst hits from GEANT with SiRasterizer" << endm; - loadFstHitsFromGEANT( mcTrackMap, hitMap, count ); - } else { - LOG_DEBUG << "Loading Fst hits from StEvent" << endm; - loadFstHitsFromStEvent( mcTrackMap, hitMap, count ); + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from StEvent" << endm; } -} // loadFstHits - -void StFwdTrackMaker::loadFstHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ + return count; +} //loadFstHitsFromStEvent +int StFwdTrackMaker::loadFstHitsFromStRnDHits( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap){ + LOG_DEBUG << "Looking for FST hits in StEvent StRnDHit Collection" << endm; + int count = 0; // Get the StEvent handle StEvent *event = (StEvent *)GetDataSet("StEvent"); - if (!event) - return; + if (!event) { + LOG_DEBUG << "No StEvent, cannot load FST FastSim hits from StEvent StRndHitCollection" << endm; + return 0; + } + size_t numFwdHitsPrior = mFwdHitsFst.size(); StRnDHitCollection *rndCollection = event->rndHitCollection(); + if (!rndCollection) return 0; const StSPtrVecRnDHit &hits = rndCollection->hits(); // we will reuse this to hold the cov mat TMatrixDSym hitCov3(3); - - mTreeData.fstN = 0; + for (unsigned int fsthit_index = 0; fsthit_index < hits.size(); fsthit_index++) { StRnDHit *hit = hits[fsthit_index]; - + if ( hit->layer() > 6 ){ // skip sTGC hits here continue; @@ -835,54 +734,64 @@ void StFwdTrackMaker::loadFstHitsFromStEvent( FwdDataSource::McTrackMap_t &mcTra hitCov3(1,0) = covmat[1][0]; hitCov3(1,1) = covmat[1][1]; hitCov3(1,2) = covmat[1][2]; hitCov3(2,0) = covmat[2][0]; hitCov3(2,1) = covmat[2][1]; hitCov3(2,2) = covmat[2][2]; - FwdHit *fhit = new FwdHit(count++, hit->position().x(), hit->position().y(), hit->position().z(), hit->layer(), hit->idTruth(), hitCov3, mcTrackMap[hit->idTruth()]); - size_t index = hit->layer()-4; - if (mGenHistograms && index < 3 ){ - ((TH2*)mHistograms[TString::Format("fsi%luHitMapZ", index).Data()]) -> Fill( hit->position().x(), hit->position().y(), hit->position().z() ); - } - - // Add the hit to the hit map - hitMap[fhit->getSector()].push_back(fhit); + mFwdHitsFst.push_back( + FwdHit( + count++, // id + hit->position().x(), hit->position().y(), hit->position().z(), // position + hit->layer(), // volume id + kFstId, // detid + hit->idTruth(), // mc track id + hitCov3, // covariance matrix + mcTrackMap[hit->idTruth()] // mcTrack + ) + ); mFstHits.push_back( TVector3( hit->position().x(), hit->position().y(), hit->position().z()) ); + } - mTreeData.fstX.push_back( hit->position().x() ); - mTreeData.fstY.push_back( hit->position().y() ); - mTreeData.fstZ.push_back( hit->position().z() ); - mTreeData.fstTrackId.push_back( hit->idTruth() ); - - mTreeData.fstN++; - + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFst.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); + // Add the hit to the hit map + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + } + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from StEvent FastSim" << endm; } + + return count; } //loadFstHitsFromStEvent -void StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap, int count ){ +int StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrackMap, FwdDataSource::HitMap_t &hitMap ){ + int count = 0; + LOG_DEBUG << "Looking for FST hits in geant struct" << endm; /************************************************************/ // Load FSI Hits from GEANT St_g2t_fts_hit *g2t_fsi_hits = (St_g2t_fts_hit *)GetDataSet("geant/g2t_fsi_hit"); - if ( !g2t_fsi_hits ) - return; + if ( !g2t_fsi_hits ){ + LOG_DEBUG << "No g2t_fts_hits, cannot load FST hits from GEANT" << endm; + return 0; + } int nfsi = g2t_fsi_hits->GetNRows(); - + size_t numFwdHitsPrior = mFwdHitsFst.size(); // reuse this to store cov mat TMatrixDSym hitCov3(3); - - if ( mGenHistograms ) mHistograms["nHitsFSI"]->Fill(nfsi); - mTreeData.fstN = 0; for (int i = 0; i < nfsi; i++) { g2t_fts_hit_st *git = (g2t_fts_hit_st *)g2t_fsi_hits->At(i); - + if (0 == git) continue; // geant hit - + int track_id = git->track_p; int volume_id = git->volume_id; // 4, 5, 6 int d = volume_id / 1000; // disk id - + int plane_id = d - 4; float x = git->x[0]; float y = git->x[1]; @@ -890,47 +799,61 @@ void StFwdTrackMaker::loadFstHitsFromGEANT( FwdDataSource::McTrackMap_t &mcTrack if (mSiRasterizer->active()) { TVector3 rastered = mSiRasterizer->raster(TVector3(git->x[0], git->x[1], git->x[2])); - - if ( mGenHistograms ) { - mHistograms["fsiHitDeltaR"]->Fill(std::sqrt(x * x + y * y) - rastered.Perp()); - mHistograms["fsiHitDeltaPhi"]->Fill(std::atan2(y, x) - rastered.Phi()); - } + LOG_INFO << TString::Format("Rastered: %f %f %f -> %f %f %f", git->x[0], git->x[1], git->x[2], rastered.X(), rastered.Y(), rastered.Z()) << endm; x = rastered.X(); y = rastered.Y(); + } else { + LOG_INFO << "Using GEANT FST hit positions without rasterization" << endm; } - - if ( mGenHistograms ) mHistograms["fsi_volume_id"]->Fill(d); - - if (plane_id < 3 && plane_id >= 0) { - - if ( mGenHistograms ) { - mHistograms[TString::Format("fsi%dHitMap", plane_id).Data()]->Fill(x, y); - mHistograms[TString::Format("fsi%dHitMapR", plane_id).Data()]->Fill(std::sqrt(x * x + y * y)); - mHistograms[TString::Format("fsi%dHitMapPhi", plane_id).Data()]->Fill(std::atan2(y, x) + TMath::Pi()); - } - } else { + if (plane_id > 3 || plane_id < 0) { continue; } hitCov3 = makeSiCovMat( TVector3( x, y, z ), mFwdConfig ); - FwdHit *hit = new FwdHit(count++, x, y, z, d, track_id, hitCov3, mcTrackMap[track_id]); + mFwdHitsFst.push_back( + FwdHit( + count++, // id + x, y, z, // position + d, // volume id + kFstId, // detid + track_id, // mc track id + hitCov3, // covariance matrix + mcTrackMap[track_id] // mcTrack + ) + ); mFstHits.push_back( TVector3( x, y, z ) ); + } - mTreeData.fstX.push_back( x ); - mTreeData.fstY.push_back( y ); - mTreeData.fstZ.push_back( z ); - mTreeData.fstTrackId.push_back( track_id ); - - mTreeData.fstN++; - + // this has to be done AFTER because the vector reallocates mem when expanding, changing addresses + size_t numFwdHitsPost = mFwdHitsFst.size(); + for ( size_t iFwdHit = numFwdHitsPrior; iFwdHit < numFwdHitsPost; iFwdHit++){ + FwdHit *hit = &(mFwdHitsFst[ iFwdHit ]); // Add the hit to the hit map - hitMap[hit->getSector()].push_back(hit); + if ( hit->getLayer() >= 0 ) + hitMap[hit->getSector()].push_back(hit); + + // add to MC track map + if ( hit->getMcTrack() ) + hit->getMcTrack()->addFstHit(hit); } + if ( numFwdHitsPost != numFwdHitsPrior ){ + LOG_INFO << "Loaded " << numFwdHitsPost - numFwdHitsPrior << " FST hits from GEANT" << endm; + } + + return count; } // loadFstHitsFromGEANT +/** + * Loads the Monte Carlo (MC) tracks from the GEANT simulation data. + * + * @param mcTrackMap A reference to the MC track map. + * + * @return The number of forward tracks. + * + * @throws None. + */ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ - LOG_DEBUG << "Looking for GEANT sim vertex info" << endm; St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); @@ -938,9 +861,15 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ if ( g2t_vertex != nullptr ) { // Set the MC Vertex for track fitting g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0); - mForwardTracker->setEventVertex( TVector3( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ) ); + TMatrixDSym cov; + cov.ResizeTo(3, 3); + cov(0, 0) = 0.001; + cov(1, 1) = 0.001; + cov(2, 2) = 0.001; + mForwardTracker->setEventVertex( TVector3( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ), cov ); } + // Get geant tracks St_g2t_track *g2t_track = (St_g2t_track *)GetDataSet("geant/g2t_track"); @@ -948,10 +877,7 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ return 0; size_t nShowers = 0; - - mTreeData.mcN = 1; LOG_DEBUG << g2t_track->GetNRows() << " mc tracks in geant/g2t_track " << endm; - if ( mGenHistograms ) mHistograms["nMcTracks"]->Fill(g2t_track->GetNRows()); for (int irow = 0; irow < g2t_track->GetNRows(); irow++) { g2t_track_st *track = (g2t_track_st *)g2t_track->At(irow); @@ -963,65 +889,38 @@ size_t StFwdTrackMaker::loadMcTracks( FwdDataSource::McTrackMap_t &mcTrackMap ){ float pt2 = track->p[0] * track->p[0] + track->p[1] * track->p[1]; float pt = std::sqrt(pt2); float eta = track->eta; + TVector3 pp( track->p[0], track->p[1], track->p[2] ); float phi = std::atan2(track->p[1], track->p[0]); //track->phi; int q = track->charge; - - if (!mcTrackMap[track_id] ) - mcTrackMap[track_id] = shared_ptr(new McTrack(pt, eta, phi, q, track->start_vertex_p)); - - if (mGenTree && (unsigned)mTreeData.mcN < MAX_TREE_ELEMENTS) { - mTreeData.mcPt.push_back( pt ); - mTreeData.mcEta.push_back( eta ); - mTreeData.mcPhi.push_back( phi ); - mTreeData.mcCharge.push_back( q ); - mTreeData.mcVertexId.push_back( track->start_vertex_p ); - - if (track->is_shower) - nShowers++; - - mTreeData.mcN++; - } else if ( mGenTree ) { - LOG_WARN << "Truncating Mc tracks in TTree output" << endm; - } + // sometimes the track->eta is wrong, pt, phi + if (!mcTrackMap[track_id] ) + mcTrackMap[track_id] = shared_ptr(new McTrack(pp.Pt(), pp.Eta(), pp.Phi(), q, track->start_vertex_p)); } // loop on track (irow) - // now check the Mc tracks against the McEvent filter size_t nForwardTracks = 0; size_t nForwardTracksNoThreshold = 0; for (auto mctm : mcTrackMap ){ if ( mctm.second == nullptr ) continue; - - if ( mGenHistograms ){ - mHistograms[ "McEventPt" ] ->Fill( mctm.second->mPt ); - mHistograms[ "McEventEta" ] ->Fill( mctm.second->mEta ); - mHistograms[ "McEventPhi" ] ->Fill( mctm.second->mPhi ); - } - if ( mctm.second->mEta > 2.5 && mctm.second->mEta < 4.0 ){ - - if ( mGenHistograms ){ - mHistograms[ "McEventFwdPt" ] ->Fill( mctm.second->mPt ); - mHistograms[ "McEventFwdEta" ] ->Fill( mctm.second->mEta ); - mHistograms[ "McEventFwdPhi" ] ->Fill( mctm.second->mPhi ); - } - nForwardTracksNoThreshold++; if ( mctm.second->mPt > 0.05 ) nForwardTracks++; } } // loop on mcTrackMap - - if ( mGenHistograms ) { - mHistograms[ "nMcTracksFwd" ]->Fill( nForwardTracks ); - mHistograms[ "nMcTracksFwdNoThreshold" ]->Fill( nForwardTracksNoThreshold ); - } - - return nForwardTracks; } // loadMcTracks +/** + * Load FCS data from StEvent for ECAL/HCAL clusters and Preshower hits (EPD). + * + * @param None + * + * @return None + * + * @throws None + */ void StFwdTrackMaker::loadFcs( ) { StEvent *stEvent = static_cast(GetInputDS("StEvent")); StFcsDb* fcsDb=static_cast(GetDataSet("fcsDb")); @@ -1035,8 +934,6 @@ void StFwdTrackMaker::loadFcs( ) { StEpdGeom epdgeo; - mTreeData.fcsN = 0; - // LOAD ECAL / HCAL CLUSTERS for ( int idet = 0; idet < 4; idet++ ){ StSPtrVecFcsCluster& clusters = fcsCol->clusters(idet); @@ -1046,13 +943,8 @@ void StFwdTrackMaker::loadFcs( ) { StThreeVectorD xyz = fcsDb->getStarXYZfromColumnRow(clu->detectorId(),clu->x(),clu->y()); mFcsClusters.push_back( TVector3( xyz.x(), xyz.y(), xyz.z() - 2 ) ); mFcsClusterEnergy.push_back( clu->energy() ); - - mTreeData.fcsX.push_back( xyz.x() ); - mTreeData.fcsY.push_back( xyz.y() ); - mTreeData.fcsZ.push_back( xyz.z() - 2 ); - mTreeData.fcsDet.push_back( idet ); - } - } + } // i + } // idet // LOAD PRESHOWER HITS (EPD) for ( int det = 4; det < 6; det ++ ) { @@ -1073,37 +965,142 @@ void StFwdTrackMaker::loadFcs( ) { double x0 = (x[0] + x[1] + x[2] + x[3]) / 4.0; double y0 = (y[0] + y[1] + y[2] + y[3]) / 4.0; mFcsPreHits.push_back( TVector3( x0, y0, zepd ) ); + } // if det + } // for i + } // for det +} // loadFcs - mTreeData.fcsX.push_back( x0 ); - mTreeData.fcsY.push_back( y0 ); - mTreeData.fcsZ.push_back( zepd ); - mTreeData.fcsDet.push_back( det ); +TVector3 StFwdTrackMaker::GetEventPrimaryVertex(){ + if ( mFwdVertexSource == kFwdVertexSourceNone ){ + // Note - maybe we will add beamline or assume some default + return TVector3(0, 0, 0); // the default vertex, but in general it should not be used + } - } - } + if ( mFwdVertexSource != kFwdVertexSourceUnknown ){ + return mEventVertex; } -} // loadFcs + mEventVertexCov.ResizeTo(3, 3); + mEventVertexCov.Zero(); + double sig2 = 1; + mEventVertexCov(0, 0) = sig2; // default resolution + mEventVertexCov(1, 1) = sig2; + mEventVertexCov(2, 2) = sig2; + // if something is found it will overwrite this, if not + // it will indicate that we have searched and found nothing + mFwdVertexSource = kFwdVertexSourceNone; + + /***************************************************** + * Add Primary Vertex to the track + */ + St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); + if ( g2t_vertex != nullptr ) { + // Set the MC Vertex for track fitting + g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(0); + + mEventVertexCov.ResizeTo(3, 3); + const double sigXY = 0.1; + const double sigZ = 10.0; + mEventVertexCov(0, 0) = pow(sigXY,2); + mEventVertexCov(1, 1) = pow(sigXY,2); + mEventVertexCov(2, 2) = pow(sigZ, 2); + auto rhc = TVectorD( 3 ); + rhc[0] = vert->ge_x[0]; + rhc[1] = vert->ge_x[1]; + rhc[2] = vert->ge_x[2]; + mEventVertex.SetXYZ( vert->ge_x[0], vert->ge_x[1], vert->ge_x[2] ); + mFwdVertexSource = kFwdVertexSourceMc; + return mEventVertex; + } + + // or try the McEvent + StMcEvent *stMcEvent = static_cast(GetInputDS("StMcEvent")); + if (stMcEvent) { + LOG_INFO << "Setting Event Vertex from StMcEvent: " << stMcEvent << endm; + StThreeVectorF vertex = stMcEvent->primaryVertex()->position(); + mEventVertex.SetXYZ( vertex.x(), vertex.y(), vertex.z() ); + mFwdVertexSource = kFwdVertexSourceMc; + LOG_INFO << "FWD Tracking on event with MC Primary Vertex: " << mEventVertex.X() << ", " << mEventVertex.Y() << ", " << mEventVertex.Z() << endm; + + mEventVertexCov(0, 0) = 0.1 * 0.1; // default resolution + mEventVertexCov(1, 1) = 0.1 * 0.1; // default resolution + mEventVertexCov(2, 2) = 0.1 * 0.1; // default resolution + return mEventVertex; + } else { + LOG_DEBUG << "No available Mc Primary Vertex" << endm; + } + + // MuDst only for now + int count = 0; + StMuDstMaker *mMuDstMaker = (StMuDstMaker *)GetMaker("MuDst"); + if(mMuDstMaker && mMuDstMaker->muDst() && mMuDstMaker->muDst()->primaryVertex() ) { + auto muPV = mMuDstMaker->muDst()->primaryVertex(); + mEventVertex.SetX(muPV->position().x()); + mEventVertex.SetY(muPV->position().y()); + mEventVertex.SetZ(muPV->position().z()); + mFwdVertexSource = kFwdVertexSourceTpc; + return mEventVertex; + } else { + LOG_DEBUG << "FWD Tracking on event without available Mu Primary Vertex" << endm; + StEvent *stEvent = static_cast(GetInputDS("StEvent")); + if (!stEvent) return mEventVertex; + StBTofCollection *btofC = stEvent->btofCollection(); + if (!btofC) { + LOG_WARN << "Cannot get BTOF collections, Cannot use VPD vertex" << endm; + return mEventVertex; + } + + StBTofHeader * btofHeader = btofC->tofHeader(); + if (!btofHeader){ + LOG_WARN << "Cannot get BTOF Header, Cannot use VPD vertex" << endm; + return mEventVertex; + } + + int nEast = btofHeader->numberOfVpdHits( east ); + int nWest = btofHeader->numberOfVpdHits( west ); + int nTof = btofC->tofHits().size(); + + if ( btofHeader->vpdVz() && fabs(btofHeader->vpdVz()) < 100 ){ + // default event vertex + LOG_DEBUG << "FWD Tracking on event using VPD z vertex: (, 0, 0, " << btofHeader->vpdVz() << " )" << endm; + mFwdVertexSource = kFwdVertexSourceVpd; + mEventVertex.SetXYZ( 0, 0, btofHeader->vpdVz() ); + return mEventVertex; + } + } + return mEventVertex; +} //________________________________________________________________________ int StFwdTrackMaker::Make() { // START time for measuring tracking long long itStart = FwdTrackerUtils::nowNanoSecond(); - // Access forward Tracker maps + StEvent *stEvent = static_cast(GetInputDS("StEvent")); + if (!stEvent) return kStOk; + + /**********************************************************************/ + // Access forward track and hit maps FwdDataSource::McTrackMap_t &mcTrackMap = mForwardData->getMcTracks(); FwdDataSource::HitMap_t &hitMap = mForwardData->getFttHits(); FwdDataSource::HitMap_t &fsiHitMap = mForwardData->getFstHits(); - - // clear vectors for visualization OBJ hits - mFttHits.clear(); - mFstHits.clear(); - mFcsPreHits.clear(); - mFcsClusters.clear(); - mFwdTracks.clear(); - - // default event vertex - mForwardTracker->setEventVertex( TVector3( 0, 0, 0 ) ); + + /**********************************************************************/ + // get the primary vertex for use with FWD tracking + mFwdVertexSource = StFwdTrackMaker::kFwdVertexSourceUnknown; + GetEventPrimaryVertex(); + LOG_DEBUG << "FWD Vertex Source: " << mFwdVertexSource << endm; + if ( mFwdVertexSource == kFwdVertexSourceNone ){ + // TODO: add clean support for beamline constraints + setIncludePrimaryVertexInFit( false ); + } else if ( mFwdVertexSource == kFwdVertexSourceUnknown ){ + LOG_WARN << "FwdVertexSource=Unknown even after looking, shouldnt be possible. Not using primary vertex in forward tracking" << endm; + // this should not be possible + setIncludePrimaryVertexInFit( false ); + } else { + LOG_DEBUG << "Setting FWD event vertex to: " << TString::Format("mEventVertex=(%0.3f+/-%0.3f, %0.3f+/-%0.3f, %0.3f+/-%0.3f)", mEventVertex.X(), sqrt(mEventVertexCov(0, 0)), mEventVertex.Y(), sqrt(mEventVertexCov(1, 1)), mEventVertex.Z(), sqrt(mEventVertexCov(2, 2)) ) << endm; + mForwardTracker->setEventVertex( mEventVertex, mEventVertexCov ); + } /**********************************************************************/ // Load MC tracks @@ -1116,18 +1113,18 @@ int StFwdTrackMaker::Make() { LOG_DEBUG << "We have " << nForwardTracks << " forward MC tracks" << endm; /**********************************************************************/ - // Load sTGC + // Load sTGC LOG_DEBUG << ">>StFwdTrackMaker::loadFttHits" << endm; if ( IAttr("useFtt") ) { loadFttHits( mcTrackMap, hitMap ); } - /**********************************************************************/ // Load FST - LOG_DEBUG << ">>StFwdTrackMaker::loadFstHits" << endm; if ( IAttr("useFst") ) { - loadFstHits( mcTrackMap, fsiHitMap ); + LOG_DEBUG << ">>StFwdTrackMaker::loadFstHits" << endm; + int fstCount = loadFstHits( mcTrackMap, fsiHitMap ); + LOG_DEBUG << "Loaded " << fstCount << " FST hits" << endm; } /**********************************************************************/ @@ -1137,104 +1134,84 @@ int StFwdTrackMaker::Make() { loadFcs(); } + /**********************************************************************/ + // Print out the MC tracks and their hit counts + for ( auto kv : mcTrackMap ){ + if ( kv.second == nullptr ) continue; + LOG_DEBUG << "MC Track: id=" << kv.first << ", nFTT=" << kv.second->mFttHits.size() << ", nFST=" << kv.second->mFstHits.size() << endm; + } + /**********************************************************************/ // Run Track finding + fitting LOG_DEBUG << ">>START Event Forward Tracking" << endm; - mForwardTracker->doEvent(); + LOG_INFO << "\tFinding FWD Track Seeds" << endm; + mForwardTracker->findTrackSeeds(); + LOG_INFO << "\tFitting FWD Track Seeds" << endm; + // in principle we could filter the track seeds further if we wanted + mForwardTracker->doTrackFitting( mForwardTracker->getTrackSeeds() ); LOG_DEBUG << "< getRecoTracks().size() << " GenFit Tracks" << endm; - + LOG_INFO << "< getTrackSeeds().size() << " Track Seeds" << endm; + LOG_INFO << "< getTrackResults().size() << " GenFit Tracks" << endm; + /**********************************************************************/ - FitVertex(); - - StEvent *stEvent = static_cast(GetInputDS("StEvent")); /**********************************************************************/ - // Run Track finding + fitting - - const auto &genfitTracks = mForwardTracker -> globalTracks(); - if ( mVisualize /* && genfitTracks.size() > 0 && genfitTracks.size() < 200*/ ) { - const auto &seed_tracks = mForwardTracker -> getRecoTracks(); + // Output track visualization if configured to do so + if ( mVisualize ){ + std::vector genfitTracks; + for ( auto gtr : mForwardTracker->getTrackResults() ) { + if ( gtr.mIsFitConvergedFully == false ) continue; + genfitTracks.push_back( gtr.mTrack.get() ); + } - ObjExporter woe; - woe.output( - TString::Format( "ev%lu", eventIndex ).Data(), - stEvent, - seed_tracks, genfitTracks, mRaveVertices, - mFttHits, mFstHits, mFcsPreHits, mFcsClusters, mFcsClusterEnergy ); - eventIndex++; - LOG_DEBUG << "Done Writing OBJ " << endm; - } else if (mVisualize && genfitTracks.size() == 0) { - LOG_DEBUG << "Skipping visualization, no FWD tracks" << endm; - } else if (mVisualize && genfitTracks.size() >= 20) { - LOG_DEBUG << "Skipping visualization, too many FWD tracks" << endm; + if ( mVisualize && genfitTracks.size() > 0 && genfitTracks.size() < 400 && eventIndex < 50 ) { + const auto &seed_tracks = mForwardTracker -> getTrackSeeds(); + + ObjExporter woe; + woe.output( + TString::Format( "ev%lu", eventIndex ).Data(), + stEvent, + seed_tracks, genfitTracks, mRaveVertices, + mFttHits, mFstHits, mFcsPreHits, mFcsClusters, mFcsClusterEnergy ); + eventIndex++; + LOG_DEBUG << "Done Writing OBJ " << endm; + } else if (mVisualize && genfitTracks.size() == 0) { + LOG_DEBUG << "Skipping visualization, no FWD tracks" << endm; + } else if (mVisualize && genfitTracks.size() >= 400) { + LOG_DEBUG << "Skipping visualization, too many FWD tracks" << endm; + } } - // Fill Track Deltas in ttree for helpful alignment info - FillTrackDeltas(); - - LOG_INFO << "Forward tracking on this event took " << (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6 << " ms" << endm; - - if ( true && IAttr("fillEvent") ) { - + LOG_DEBUG << "Forward tracking on this event took " << (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6 << " ms" << endm; + if ( IAttr("fillEvent") ) { if (!stEvent) { LOG_WARN << "No StEvent found. Forward tracks will not be saved" << endm; return kStWarn; } - FillEvent(); } // IAttr FillEvent - LOG_DEBUG << "Filling fwd Tree for event: " << GetIventNumber() << endm; - FillTTree(); return kStOK; } // Make - +/** + * Creates a StFwdTrack object from a GenfitTrackResult. + * + * @param gtr The GenfitTrackResult object containing the track information. + * @param indexTrack The index of the track. + * + * @return A pointer to the created StFwdTrack object, or nullptr if the GenfitTrackResult is nullptr. + * + * @throws None. + */ StFwdTrack * StFwdTrackMaker::makeStFwdTrack( GenfitTrackResult >r, size_t indexTrack ){ LOG_DEBUG << "StFwdTrackMaker::makeStFwdTrack()" << endm; - StFwdTrack *fwdTrack = new StFwdTrack( ); - - auto track = gtr.track; - // if FST refit is available save that - if ( gtr.nFST > 0 && gtr.fstTrack != nullptr){ - LOG_DEBUG << "\tSave FST refit track since we have FST points" << endm; - track = gtr.fstTrack; - } else if (gtr.nFST > 0 && gtr.fstTrack == nullptr) { - LOG_WARN << "\tFST refit failed even though we have " << gtr.nFST << " FST points" << endm; - } - - // Fit failed beyond use - if ( track == nullptr ){ - LOG_DEBUG << "Track is nullptr, not saving StFwdTrack" << endm; - return nullptr; - } - - auto fitStatus = track->getFitStatus(); - if ( !fitStatus ) - return nullptr; - - // Fill charge and quality info - fwdTrack->setDidFitConverge( fitStatus->isFitConverged() ); - fwdTrack->setDidFitConvergeFully( fitStatus->isFitConvergedFully() ); - fwdTrack->setNumberOfFailedPoints( fitStatus->getNFailedPoints() ); - - fwdTrack->setNumberOfFitPoints( track->getNumPoints() ); - fwdTrack->setChi2( fitStatus->getChi2() ); - fwdTrack->setNDF( fitStatus->getNdf() ); - fwdTrack->setPval( fitStatus->getPVal() ); - - auto cr = track->getCardinalRep(); - // charge at first point - fwdTrack->setCharge( gtr.charge ); - - TVector3 p = cr->getMom( track->getFittedState( 0, cr )); - fwdTrack->setPrimaryMomentum( StThreeVectorD( gtr.momentum.X(), gtr.momentum.Y(), gtr.momentum.Z() ) ); - LOG_DEBUG << "Making StFwdTrack with " << TString::Format( "p=(%f, %f, %f)", fwdTrack->momentum().x(), fwdTrack->momentum().y(), fwdTrack->momentum().z() ) << endm; + StFwdTrack *fwdTrack = new StFwdTrack( ); + /*******************************************************************************/ + // store the seed points for the track int nSeedPoints = 0; - // store the seed points from FTT - for ( auto s : gtr.trackSeed ){ + for ( auto s : gtr.mSeed ){ FwdHit * fh = static_cast( s ); if (!fh) continue; float cov[9]; @@ -1242,101 +1219,112 @@ StFwdTrack * StFwdTrackMaker::makeStFwdTrack( GenfitTrackResult >r, size_t ind cov[1] = fh->_covmat(0,1); cov[4] = fh->_covmat(1,1); cov[7] = fh->_covmat(2,1); cov[2] = fh->_covmat(0,2); cov[5] = fh->_covmat(1,2); cov[8] = fh->_covmat(2,2); - StFwdTrackSeedPoint p( StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), fh->getSector(), fh->getTrackId(), cov ); - fwdTrack->mFTTPoints.push_back( p ); - nSeedPoints++; - } - - for ( auto s : gtr.fstSeed ){ - FwdHit * fh = static_cast( s ); - if (!fh) continue; - float cov[9]; - cov[0] = fh->_covmat(0,0); cov[3] = fh->_covmat(1,0); cov[6] = fh->_covmat(2,0); - cov[1] = fh->_covmat(0,1); cov[4] = fh->_covmat(1,1); cov[7] = fh->_covmat(2,1); - cov[2] = fh->_covmat(0,2); cov[5] = fh->_covmat(1,2); cov[8] = fh->_covmat(2,2); + StFwdTrackSeedPoint p( + StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), + fh->_detid * 10 + fh->getSector(), // 10 * detid + sector + fh->getTrackId(), + cov + ); + if ( fh->isFst() ) + fwdTrack->mFSTPoints.push_back( p ); + else if ( fh->isFtt() ) + fwdTrack->mFTTPoints.push_back( p ); - StFwdTrackSeedPoint p( StThreeVectorD( fh->getX(), fh->getY(), fh->getZ() ), fh->getSector(), fh->getTrackId(), cov ); - fwdTrack->mFSTPoints.push_back( p ); nSeedPoints++; } // set total number of seed points fwdTrack->setNumberOfSeedPoints( nSeedPoints ); + int idt = 0; + double qual = 0; + idt = MCTruthUtils::dominantContribution(gtr.mSeed, qual); + fwdTrack->setMc( idt, qual*100 ); // QAtruth stored as UChar_t + LOG_DEBUG << "Dominant contribution: " << idt << " with quality " << qual << endm; - // compute projections to z-planes of various detectors - vector zPlanes = { - 0, // PV TODO, update with event vertex? - 151.750000, 165.248001, 178.781006, // FST - 280.904999, 303.704987, 326.605011, 349.404999, // FTT - 375.0, // EPD - 715.0, //ECAL - 807.0 // HCAL - }; - - // Note: as discussed, after verification storage of the projections - // @ the FST and FTT may no longer be needed, not saved in e.g. MuDst + // Fit failed beyond use + if ( gtr.mTrack == nullptr ){ + gtr.Clear(); + LOG_DEBUG << "GenfitTrack is nullptr, making StFwdTrack with seed info only" << endm; + return fwdTrack; + } + // Fill charge and quality info + fwdTrack->setDidFitConverge( gtr.mStatus->isFitConverged() ); + fwdTrack->setDidFitConvergeFully( gtr.mStatus->isFitConvergedFully() ); + fwdTrack->setNumberOfFailedPoints( gtr.mStatus->getNFailedPoints() ); - // this should always be the case, but being careful - if (gGeoManager) { - FwdGeomUtils fwdGeoUtils( gGeoManager ); - - // get the z-locations from geometry model and fallback to the defaults - auto fstZ = fwdGeoUtils.fstZ( {151.750000, 165.248001, 178.781006} ); - auto fttZ = fwdGeoUtils.fttZ( {280.904999, 303.704987, 326.605011, 349.404999} ); + fwdTrack->setNumberOfFitPoints( gtr.mTrack->getNumPoints() ); + fwdTrack->setChi2( gtr.mStatus->getChi2() ); + fwdTrack->setNDF( gtr.mStatus->getNdf() ); + fwdTrack->setPval( gtr.mStatus->getPVal() ); + + // charge at first point + fwdTrack->setCharge( gtr.mCharge ); + fwdTrack->setDCA( gtr.mDCA.X(), gtr.mDCA.Y(), gtr.mDCA.Z() ); + + TVector3 p = gtr.mMomentum;//cr->getMom( gtr.mTrack->getFittedState( 0, cr )); + fwdTrack->setPrimaryMomentum( StThreeVectorD( gtr.mMomentum.X(), gtr.mMomentum.Y(), gtr.mMomentum.Z() ) ); + + if ( gtr.isPrimary ){ + fwdTrack->setVtxIndex( 0 ); + } else { + fwdTrack->setVtxIndex( UCHAR_MAX ); + } + + /*******************************************************************************/ + // if the track is not (at least partially) converged, do not try to project it + if ( !gtr.mStatus->isFitConvergedPartially() ){ + gtr.Clear(); + return fwdTrack; + } - // copy new values into the zPlanes vector - std::copy( fstZ.begin(), fstZ.end(), zPlanes.begin()+1 ); - std::copy( fttZ.begin(), fttZ.end(), zPlanes.begin()+4 ); - } - - // Match these to the z-planes above - const int FST = kFstId; - const int FTT = kFttId; - vector detMap = { - kTpcId, - FST, FST, FST, - FTT, FTT, FTT, FTT, - kFcsPresId, - kFcsWcalId, - kFcsHcalId + /*******************************************************************************/ + // compute projections to z-planes of various detectors + // TODO: update FCS to use correct z + angle + map mapDetectorToZPlane = { + { kTpcId, 0.0 }, + { kFstId, mFstZFromGeom[0] }, + { kFstId, mFstZFromGeom[1] }, + { kFstId, mFstZFromGeom[2] }, + { kFttId, mFttZFromGeom[0] }, + { kFttId, mFttZFromGeom[1] }, + { kFttId, mFttZFromGeom[2] }, + { kFttId, mFttZFromGeom[3] }, + { kFcsPresId, 375.0 }, + { kFcsWcalId, 715.0 }, + { kFcsHcalId, 807.0 } }; size_t zIndex = 0; - int detIndex = 0; - for ( float z : zPlanes ){ - detIndex = detMap[ zIndex]; - // LOG_DEBUG << "Calculating Projection for detId=" << detIndex << " @ z=" << z << endm; - TVector3 mom(0, 0, 0); - float cov[9]; - - TVector3 tv3(0, 0, 0); - if ( detIndex != kFcsHcalId ){ - tv3 = ObjExporter::trackPosition( track, z, cov, mom ); + TVector3 mom(0, 0, 0); + float cov[9]; + TVector3 tv3(0, 0, 0); + for ( auto zp : mapDetectorToZPlane ){ + int detIndex = zp.first; + float z = zp.second; + tv3.SetXYZ(0, 0, 0); + if ( detIndex != kFcsHcalId && detIndex != kFcsWcalId ){ + tv3 = ObjExporter::trackPosition( gtr.mTrack.get(), z, cov, mom ); } else { // use a straight line projection to HCAL since GenFit cannot handle long projections - tv3 = ObjExporter::projectAsStraightLine( track, 575.0, 625.0, z, cov, mom ); + tv3 = ObjExporter::projectAsStraightLine( gtr.mTrack.get(), 575.0, 625.0, z, cov, mom ); } fwdTrack->mProjections.push_back( StFwdTrackProjection( detIndex, StThreeVectorF( tv3.X(), tv3.Y(), tv3.Z() ), StThreeVectorF( mom.X(), mom.Y(), mom.Z() ), cov) ); - - // // Add Proj info to TTree - mTreeData.tprojX.push_back( tv3.X() ); - mTreeData.tprojY.push_back( tv3.Y() ); - mTreeData.tprojZ.push_back( tv3.Z() ); - mTreeData.tprojIdD.push_back( detIndex ); - mTreeData.tprojIdT.push_back( indexTrack ); - zIndex++; } + /*******************************************************************************/ - return fwdTrack; + /*******************************************************************************/ + // clear the GenfitTrackResult + gtr.Clear(); + + // return the StFwdTrack we made + return fwdTrack; } void StFwdTrackMaker::FillEvent() { - LOG_DEBUG << "StFwdTrackMaker::FillEvent()" << endm; - // Now fill StEvent StEvent *stEvent = static_cast(GetInputDS("StEvent")); - - // FillEvent(); + if (!stEvent) + return; StFwdTrackCollection * ftc = stEvent->fwdTrackCollection(); if ( !ftc ){ LOG_INFO << "Creating the StFwdTrackCollection" << endm; @@ -1344,57 +1332,34 @@ void StFwdTrackMaker::FillEvent() { stEvent->setFwdTrackCollection( ftc ); } - mTreeData.tprojN = 0; - mTreeData.tprojX.clear(); - mTreeData.tprojY.clear(); - mTreeData.tprojZ.clear(); - mTreeData.tprojIdD.clear(); - mTreeData.tprojIdT.clear(); - size_t indexTrack = 0; + size_t indexTrack = 0; for ( auto gtr : mForwardTracker->getTrackResults() ) { - StFwdTrack* fwdTrack = makeStFwdTrack( gtr, indexTrack ); - if (nullptr == fwdTrack) - continue; - ftc->addTrack( fwdTrack ); + StFwdTrack* fwdTrack = makeStFwdTrack( gtr, indexTrack ); + indexTrack++; + if (nullptr == fwdTrack) + continue; + ftc->addTrack( fwdTrack ); } + LOG_INFO << "StFwdTrackCollection has " << ftc->numberOfTracks() << " tracks now" << endm; - mTreeData.tprojN = mTreeData.tprojX.size(); - LOG_DEBUG << "StFwdTrackCollection has " << ftc->numberOfTracks() << " tracks now" << endm; - ProcessFwdTracks(); -} - -void StFwdTrackMaker::FillTrackDeltas(){ - LOG_DEBUG << "Filling Track Deltas for Alignment" << endm; - const auto &fittedTracks = mForwardTracker -> getTrackResults(); - - for ( size_t i = 0; i < fittedTracks.size(); i++ ){ - auto st = fittedTracks[i].trackSeed; - auto gt = fittedTracks[i].track; - - if (fittedTracks[i].isFitConvergedFully == false){ - LOG_DEBUG << "Skipping track, failed fit" << endm; - continue; - } - - for ( KiTrack::IHit * hit : st ){ - TVector3 htv3(hit->getX(), hit->getY(), hit->getZ()); - - auto ttv3 = ObjExporter::trackPosition( gt, htv3.Z() ); - - mTreeData.thdX.push_back( (ttv3.X() - htv3.X()) ); - mTreeData.thdY.push_back( (ttv3.Y() - htv3.Y()) ); - mTreeData.thaX.push_back( htv3.X() ); - mTreeData.thaY.push_back( htv3.Y() ); - mTreeData.thaZ.push_back( htv3.Z() ); - mTreeData.thdN++; - } + // Pico Dst requires a primary vertex, + // if we have a PicoDst maker in the chain, we need to add a primary vertex + // when one does not exist to get a "FWD" picoDst + auto mk = GetMaker("PicoDst"); + if ( mk && stEvent->numberOfPrimaryVertices() == 0 ){ + LOG_INFO << "Adding a primary vertex to StEvent since PicoDst maker was found in chain, but no vertices found" << endm; + stEvent->addPrimaryVertex( new StPrimaryVertex() ); + LOG_INFO << "StPrimaryVertex::numberOfPrimaryVertices = " << stEvent->numberOfPrimaryVertices() << endm; } -} //FillTrackDeltas + + // ProcessFwdTracks(); +} void StFwdTrackMaker::FitVertex(){ - const auto &genfitTracks = mForwardTracker -> globalTracks(); + vector genfitTracks; + const auto &trackResults = mForwardTracker -> getTrackResults(); if ( genfitTracks.size() >= 2 ){ genfit::GFRaveVertexFactory gfrvf; @@ -1404,281 +1369,34 @@ void StFwdTrackMaker::FitVertex(){ bscm(1, 1) = bssXY*bssXY; bscm(2, 2) = 50.5 * 50.5; gfrvf.setBeamspot( TVector3( 0, 0, 0 ), bscm ); - // std::vector< genfit::GFRaveVertex * > vertices; - const auto &genfitTracks = mForwardTracker -> globalTracks(); + mRaveVertices.clear(); gfrvf.findVertices( &mRaveVertices, genfitTracks, false ); - + LOG_DEBUG << "mRaveVertices.size() = " << mRaveVertices.size() << endm; - for ( auto vert : mRaveVertices ){ LOG_DEBUG << TString::Format( "RAVE vertex @(%f, %f, %f)\n\n", vert->getPos().X(), vert->getPos().Y(), vert->getPos().Z() ) << endm; } } -} - -void StFwdTrackMaker::FillTTree(){ - - St_g2t_vertex *g2t_vertex = (St_g2t_vertex *)GetDataSet("geant/g2t_vertex"); - if (mGenTree) { - - // VERTICES - if ( g2t_vertex ){ - mTreeData.vmcN = g2t_vertex->GetNRows(); - if ( (unsigned)mTreeData.vmcN >= MAX_TREE_ELEMENTS ) mTreeData.vmcN = MAX_TREE_ELEMENTS; - LOG_INFO << "Saving " << mTreeData.vmcN << " vertices in TTree" << endm; - for ( int i = 0; i < mTreeData.vmcN; i++ ){ - g2t_vertex_st *vert = (g2t_vertex_st*)g2t_vertex->At(i); - mTreeData.vmcX.push_back( vert->ge_x[0] ); - mTreeData.vmcY.push_back( vert->ge_x[1] ); - mTreeData.vmcZ.push_back( vert->ge_x[2] ); - } - } - - // RAVE RECO VERTICES - mTreeData.vrcN = mRaveVertices.size(); - if ( (unsigned)mTreeData.vrcN >= MAX_TREE_ELEMENTS ) mTreeData.vrcN = MAX_TREE_ELEMENTS; - LOG_INFO << "Saving " << mTreeData.vrcN << " RAVE vertices in TTree" << endm; - for ( int i = 0; i < mTreeData.vrcN; i++ ) { - auto vert = mRaveVertices[i]; - mTreeData.vrcX.push_back( vert->getPos().X() ); - mTreeData.vrcY.push_back( vert->getPos().Y() ); - mTreeData.vrcZ.push_back( vert->getPos().Z() ); - } - - - - - if (mForwardTracker->getSaveCriteriaValues() && mTreeData.saveCrit ) { - for (auto crit : mForwardTracker->getTwoHitCriteria()) { - string name = crit->getName(); - - // special, save all hit info for this one - - - if ( name == "Crit2_BDT" ){ - mTreeData.Crits["Crit2_BDT_DeltaPhi"].clear(); - mTreeData.Crits["Crit2_BDT_DeltaRho"].clear(); - mTreeData.Crits["Crit2_BDT_RZRatio"].clear(); - mTreeData.Crits["Crit2_BDT_StraightTrackRatio"].clear(); - - for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { - mTreeData.Crits["Crit2_BDT_DeltaPhi"].push_back( kv["Crit2_BDT_DeltaPhi"] ); - mTreeData.Crits["Crit2_BDT_DeltaRho"].push_back( kv["Crit2_BDT_DeltaRho"] ); - mTreeData.Crits["Crit2_BDT_RZRatio"].push_back( kv["Crit2_BDT_RZRatio"] ); - mTreeData.Crits["Crit2_BDT_StraightTrackRatio"].push_back( kv["Crit2_BDT_StraightTrackRatio"] ); - } - - } - - if ( name == "Crit2_RZRatio" ){ - LOG_INFO << "allValues.size() = " << mForwardTracker->getCriteriaAllValues(name).size() << " == " << mForwardTracker->getCriteriaTrackIds(name).size() << endm; - assert( mForwardTracker->getCriteriaAllValues(name).size() == mForwardTracker->getCriteriaTrackIds(name).size() && " Crit lengths must be equal" ); - mTreeData.Crits["Crit2_RZRatio_x1"].clear(); - mTreeData.Crits["Crit2_RZRatio_y1"].clear(); - mTreeData.Crits["Crit2_RZRatio_z1"].clear(); - mTreeData.Crits["Crit2_RZRatio_x2"].clear(); - mTreeData.Crits["Crit2_RZRatio_y2"].clear(); - mTreeData.Crits["Crit2_RZRatio_z2"].clear(); - - mTreeData.CritTrackIds["Crit2_RZRatio_h1"].clear(); - mTreeData.CritTrackIds["Crit2_RZRatio_h2"].clear(); - mTreeData.CritTrackIds["Crit2_RZRatio_h3"].clear(); - - - for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { - mTreeData.Crits["Crit2_RZRatio_x1"].push_back( kv["Crit2_RZRatio_x1"] ); - mTreeData.Crits["Crit2_RZRatio_y1"].push_back( kv["Crit2_RZRatio_y1"] ); - mTreeData.Crits["Crit2_RZRatio_z1"].push_back( kv["Crit2_RZRatio_z1"] ); - - mTreeData.Crits["Crit2_RZRatio_x2"].push_back( kv["Crit2_RZRatio_x2"] ); - mTreeData.Crits["Crit2_RZRatio_y2"].push_back( kv["Crit2_RZRatio_y2"] ); - mTreeData.Crits["Crit2_RZRatio_z2"].push_back( kv["Crit2_RZRatio_z2"] ); - - mTreeData.CritTrackIds["Crit2_RZRatio_h1"].push_back( kv["Crit2_RZRatio_h1"] ); - mTreeData.CritTrackIds["Crit2_RZRatio_h2"].push_back( kv["Crit2_RZRatio_h2"] ); - mTreeData.CritTrackIds["Crit2_RZRatio_h3"].push_back( -1 ); - } - } - - - LOG_DEBUG << "Saving Criteria values from " << name << " in TTree" << endm; - mTreeData.Crits[name].clear(); - mTreeData.CritTrackIds[name].clear(); - // copy by value so ROOT doesnt get lost (uses pointer to vector) - for (float v : mForwardTracker->getCriteriaValues(name)) { - mTreeData.Crits[name].push_back(v); - } - for (int v : mForwardTracker->getCriteriaTrackIds(name)) { - mTreeData.CritTrackIds[name].push_back(v); - } - } - - // three hit criteria - for (auto crit : mForwardTracker->getThreeHitCriteria()) { - string name = crit->getName(); - - // special, save all hit info for this one - if ( name == "Crit2_RZRatio" ){ - LOG_INFO << "allValues.size() = " << mForwardTracker->getCriteriaAllValues(name).size() << " == " << mForwardTracker->getCriteriaTrackIds(name).size() << endm; - assert( mForwardTracker->getCriteriaAllValues(name).size() == mForwardTracker->getCriteriaTrackIds(name).size() && " Crit lengths must be equal" ); - - mTreeData.CritTrackIds["Crit2_RZRatio_h1"].clear(); - mTreeData.CritTrackIds["Crit2_RZRatio_h2"].clear(); - mTreeData.CritTrackIds["Crit2_RZRatio_h3"].clear(); - - for (auto kv : mForwardTracker->getCriteriaAllValues(name)) { - mTreeData.CritTrackIds["Crit2_RZRatio_h1"].push_back( kv["Crit2_RZRatio_h1"] ); - mTreeData.CritTrackIds["Crit2_RZRatio_h2"].push_back( kv["Crit2_RZRatio_h2"] ); - mTreeData.CritTrackIds["Crit2_RZRatio_h3"].push_back( kv["Crit2_RZRatio_h3"] ); - } - } - - - LOG_DEBUG << "Saving Criteria values from " << name << " in TTree" << endm; - mTreeData.Crits[name].clear(); - mTreeData.CritTrackIds[name].clear(); - // copy by value so ROOT doesnt get lost (uses pointer to vector) - for (float v : mForwardTracker->getCriteriaValues(name)) { - mTreeData.Crits[name].push_back(v); - } - for (int v : mForwardTracker->getCriteriaTrackIds(name)) { - mTreeData.CritTrackIds[name].push_back(v); - } - } - - // clear them - mForwardTracker->clearSavedCriteriaValues(); - } - - // SAVE RECO tracks - - mTreeData.rcN = 0; - const auto &fittedTracks = mForwardTracker -> getTrackResults(); - - LOG_INFO << "There are " << fittedTracks.size() << " seed tracks to save" << endm; - size_t maxToSave = fittedTracks.size(); - if (maxToSave >= 200) { - maxToSave = 0; - LOG_INFO << "More than 200 tracks , not saving unfit tracks" << endm; - } - - for ( size_t i = 0; i < maxToSave; i++ ){ - if ( i >= MAX_TREE_ELEMENTS ){ - LOG_WARN << "Truncating Reco tracks in TTree output" << endm; - break; - } - - int idt = 0; - double qual = 0; - idt = MCTruthUtils::dominantContribution(fittedTracks[i].trackSeed, qual); - - if ( fittedTracks[i].track == nullptr || fittedTracks[i].trackRep == nullptr ) { - LOG_INFO << "Skip saving null track" << endm; - continue; - } - - if ( fittedTracks[i].isFitConverged == false ){ - LOG_INFO << "Skip saving track where fit did not converge" << endm; - continue; - } - - - mTreeData.rcQuality.push_back( qual ); - mTreeData.rcTrackId.push_back( idt ); - - mTreeData.rcCharge.push_back( fittedTracks[i].charge ); - mTreeData.rcPt.push_back( fittedTracks[i].momentum.Pt() ); - mTreeData.rcEta.push_back( fittedTracks[i].momentum.Eta() ); - mTreeData.rcPhi.push_back( fittedTracks[i].momentum.Phi() ); - - mTreeData.rcNumPV.push_back( fittedTracks[i].nPV ); - mTreeData.rcNumFTT.push_back( fittedTracks[i].nFTT ); - mTreeData.rcNumFST.push_back( fittedTracks[i].nFST ); - - mTreeData.rcN ++; - } - LOG_INFO << "Filling TTree" << endm; - mTree->Fill(); - } // if mGenTree -} - +} // FitVertex //________________________________________________________________________ void StFwdTrackMaker::Clear(const Option_t *opts) { LOG_DEBUG << "StFwdTrackMaker::CLEAR" << endm; mForwardData->clear(); + mForwardTracker->Clear(); + + // clear fwd hits from fst and ftt + mFwdHitsFst.clear(); + mFwdHitsFtt.clear(); + + // clear vectors for visualization OBJ hits + mFttHits.clear(); + mFstHits.clear(); + mFcsPreHits.clear(); + mFcsClusters.clear(); + mFwdTracks.clear(); - if (mGenTree){ - mTreeData.thdN = mTreeData.fttN = mTreeData.rcN = mTreeData.mcN = mTreeData.vmcN = mTreeData.vrcN = mTreeData.fcsN = 0; - mTreeData.fttX.clear(); - mTreeData.fttY.clear(); - mTreeData.fttZ.clear(); - mTreeData.fttTrackId.clear(); - mTreeData.fttVolumeId.clear(); - mTreeData.fttPt.clear(); - mTreeData.fttVertexId.clear(); - - mTreeData.fstX.clear(); - mTreeData.fstY.clear(); - mTreeData.fstZ.clear(); - mTreeData.fstTrackId.clear(); - - mTreeData.fcsX.clear(); - mTreeData.fcsY.clear(); - mTreeData.fcsZ.clear(); - mTreeData.fcsDet.clear(); - - mTreeData.rcPt.clear(); - mTreeData.rcEta.clear(); - mTreeData.rcPhi.clear(); - mTreeData.rcQuality.clear(); - mTreeData.rcTrackId.clear(); - mTreeData.rcNumFST.clear(); - mTreeData.rcCharge.clear(); - mTreeData.rcNumFTT.clear(); - mTreeData.rcNumPV.clear(); - - - mTreeData.mcPt.clear(); - mTreeData.mcEta.clear(); - mTreeData.mcPhi.clear(); - mTreeData.mcVertexId.clear(); - mTreeData.mcCharge.clear(); - mTreeData.vmcX.clear(); - mTreeData.vmcY.clear(); - mTreeData.vmcZ.clear(); - - mTreeData.tprojX.clear(); - mTreeData.tprojY.clear(); - mTreeData.tprojZ.clear(); - mTreeData.tprojPx.clear(); - mTreeData.tprojPy.clear(); - mTreeData.tprojPz.clear(); - mTreeData.vrcX.clear(); - mTreeData.vrcY.clear(); - mTreeData.vrcZ.clear(); - mTreeData.thdX.clear(); - mTreeData.thdY.clear(); - mTreeData.thaX.clear(); - mTreeData.thaY.clear(); - mTreeData.thaZ.clear(); - - mTreeData.thdX.clear(); - mTreeData.thdY.clear(); - mTreeData.thaX.clear(); - mTreeData.thaY.clear(); - mTreeData.thaZ.clear(); - - mTreeData.fttN = 0; - mTreeData.fstN = 0; - mTreeData.rcN = 0; - mTreeData.mcN = 0; - mTreeData.vmcN = 0; - mTreeData.tprojN = 0; - mTreeData.vrcN = 0; - mTreeData.thdN = 0; - } } //________________________________________________________________________ void StFwdTrackMaker::ProcessFwdTracks( ){ @@ -1699,9 +1417,7 @@ std::string StFwdTrackMaker::defaultConfigIdealSim = R"( - - - + @@ -1715,39 +1431,49 @@ std::string StFwdTrackMaker::defaultConfigData = R"( - + - + - - - - + + + + - + + - + - + 0.99 0.001 - + - - - + + + -)"; \ No newline at end of file +)"; + + +const std::vector &StFwdTrackMaker::getTrackSeeds() const{ + return mForwardTracker->getTrackSeeds(); +} + +const std::vector &StFwdTrackMaker::getFitResults()const{ + return mForwardTracker->getTrackResults(); +} diff --git a/StRoot/StFwdTrackMaker/StFwdTrackMaker.h b/StRoot/StFwdTrackMaker/StFwdTrackMaker.h index e04c158bb45..819b3ed0934 100644 --- a/StRoot/StFwdTrackMaker/StFwdTrackMaker.h +++ b/StRoot/StFwdTrackMaker/StFwdTrackMaker.h @@ -5,10 +5,12 @@ #ifndef __CINT__ #include "GenFit/Track.h" +#include "StFwdTrackMaker/include/Tracker/FwdHit.h" #endif #include "FwdTrackerConfig.h" #include "TVector3.h" +#include "TMatrix.h" namespace KiTrack { class IHit; @@ -38,67 +40,10 @@ class McTrack; // STL includes #include #include - - -// 877-369-6347 class StFwdTrack; class GenfitTrackResult; - -const size_t MAX_TREE_ELEMENTS = 4000; -struct FwdTreeData { - - // hits; - int fttN; - vector fttX, fttY, fttZ; - vector fttVolumeId; - // Only avalaible for hits if MC - vector fttPt; - vector fttTrackId, fttVertexId; - - // hits; - int fstN; - vector fstX, fstY, fstZ; - vector fstTrackId; - - int fcsN; - vector fcsX, fcsY, fcsZ; - vector fcsDet; - - // RC tracks - int rcN; - vector rcPt, rcEta, rcPhi, rcQuality; - vector rcTrackId, rcNumFST, rcCharge, rcNumFTT, rcNumPV; - - // MC Tracks - int mcN; - vector mcPt, mcEta, mcPhi; - vector mcVertexId, mcCharge; - - // MC Level vertex info - // maybe use also for TPC vertex if available in data - int vmcN; - vector vmcX, vmcY, vmcZ; - - int tprojN; - vector tprojX, tprojY, tprojZ; - vector tprojPx, tprojPy, tprojPz; - vector tprojIdD, tprojIdT; - - // RAVE reco vertices - int vrcN; - vector vrcX, vrcY, vrcZ; - - int thdN; - vector thdX, thdY, thaX, thaY, thaZ; - - bool saveCrit = false; - std::map> Crits; - std::map> CritTrackIds; - -}; - class StFwdTrackMaker : public StMaker { ClassDef(StFwdTrackMaker, 0); @@ -120,34 +65,41 @@ class StFwdTrackMaker : public StMaker { LoadConfiguration(); } void LoadConfiguration(); - void SetGenerateHistograms( bool _genHisto ){ mGenHistograms = _genHisto; } - void SetGenerateTree(bool _genTree) { mGenTree = _genTree; } void SetVisualize( bool _viz ) { mVisualize = _viz; } vector mFwdTracks; + vector &GetFttHits() { return mFwdHitsFtt; } + vector &GetFstHits() { return mFwdHitsFst; } + + #ifndef __CINT__ + // Get the FwdTracker object + std::shared_ptr GetForwardTracker() { return mForwardTracker; } + const std::vector &getTrackSeeds() const; + const std::vector &getFitResults() const; + #endif + TVector3 GetEventPrimaryVertex(); + private: protected: - // Track Seed typdef - typedef std::vector Seed_t; + // Event Filters + float mEventFilterMinTofMult = 2; + bool mEventFilterRequireEventVertex = false; + bool mEventFilterRequireVpdVertex = true; + float mEventFilterMinVpdZ = -99; + float mEventFilterMaxVpdZ = 99; - // for Wavefront OBJ export - size_t eventIndex = 0; - + size_t eventIndex = 0; // counts up for processed events + size_t mEventNum = 0; // global event num (index) + TVector3 mEventVertex; // primary vertex used in fwd tracking this event - bool mGenHistograms = false; - bool mGenTree = false; std::string mConfigFile; - std::map mHistograms; - TFile *mTreeFile = nullptr; - TTree *mTree = nullptr; - FwdTreeData mTreeData; - bool mVisualize = false; + bool mVisualize = false; // if true,write out a Wavefront OBJ to visualize the event in 3D vector mFttHits; vector mFstHits; vector mFcsClusters; @@ -155,175 +107,193 @@ class StFwdTrackMaker : public StMaker { vector mFcsPreHits; std::vector< genfit::GFRaveVertex * > mRaveVertices; + vector mFttZFromGeom, mFstZFromGeom; void ProcessFwdTracks(); void FillEvent(); void FillTrackDeltas(); + bool SkipEvent(); StFwdTrack * makeStFwdTrack( GenfitTrackResult >r, size_t indexTrack ); // I could not get the library generation to succeed with these. // so I have removed them #ifndef __CINT__ + TMatrixDSym mEventVertexCov; // covariance matrix for the primary vertex + enum FwdVertexSource { kFwdVertexSourceUnknown, kFwdVertexSourceNone, kFwdVertexSourceTpc, kFwdVertexSourceMc, kFwdVertexSourceVpd }; // unknown means we havent looked yet + FwdVertexSource mFwdVertexSource = StFwdTrackMaker::kFwdVertexSourceUnknown; + vector mFwdHitsFtt; + vector mFwdHitsFst; std::shared_ptr mSiRasterizer; FwdTrackerConfig mFwdConfig; std::shared_ptr mForwardTracker; std::shared_ptr mForwardData; - size_t loadMcTracks( std::map> &mcTrackMap ); void loadFcs(); void loadFttHits( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); void loadFttHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); void loadFttHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); - void loadFstHits( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); - void loadFstHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); - void loadFstHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap, int count = 0 ); + int loadFstHits( std::map> &mcTrackMap, std::map> &hitMap ); + int loadFstHitsFromMuDst( std::map> &mcTrackMap, std::map> &hitMap ); + int loadFstHitsFromGEANT( std::map> &mcTrackMap, std::map> &hitMap ); + int loadFstHitsFromStEvent( std::map> &mcTrackMap, std::map> &hitMap ); + int loadFstHitsFromStRnDHits( std::map> &mcTrackMap, std::map> &hitMap ); #endif - void FillTTree(); // if debugging ttree is turned on (mGenTree) + + /** @brief Fit the primary vertex using FWD tracks */ void FitVertex(); static std::string defaultConfigIdealSim; static std::string defaultConfigData; std::string defaultConfig; bool configLoaded = false; + TString mGeoCache; // Helper functions for modifying configuration // NOTE: to override configuration, call individual functions after setConfigForXXX public: - /**@brief Setup the StFwdTrackMaker for running on Data - * Load the default configuration for Data. + /** @brief Setup the StFwdTrackMaker for running on Data + * Load the default configuration for Data. * Note: Apply any overrides after calling this */ void setConfigForData() { defaultConfig = defaultConfigData; LoadConfiguration(); } - /**@brief Setup the StFwdTrackMaker for running on Data + /** @brief Setup the StFwdTrackMaker for running on Data * Load the default configuration for IDEAL simulation. * This runs with MC track finding and MC-seeded track fitting. - * - MC track finding uses the MCTrackId to collect stgc/fst hits into track seeds + * - MC track finding uses the MCTrackId to collect stgc/fst hits into track seeds * - MC-seeded track fitting uses the MC particle momentum to seed the track fit * - Also uses the simulated MC primary vertex with smearing according to the simgaXY,Z * Note: Apply any overrides after calling this */ void setConfigForIdealSim() { defaultConfig = defaultConfigIdealSim; LoadConfiguration(); } - /**@brief Setup the StFwdTrackMaker for running on Data + /** @brief Setup the StFwdTrackMaker for running on Data * Load the default configuration for Realistic simulation. * This runs tracking on simulation using the same parameters / approach as on data. * Note: Apply any overrides after calling this */ - void setConfigForRealisticSim() { - defaultConfig = defaultConfigData; - LoadConfiguration(); + void setConfigForRealisticSim() { + defaultConfig = defaultConfigData; + LoadConfiguration(); // Note: Once the slow sims work this override will not be needed // because the slow sims will put hits into StEvent just like (data) reco chain setFttHitSource( "GEANT" ); } - /**@brief Set the filename for output ROOT file + /** @brief Set the filename for output ROOT file * @param fn : filename of output ROOT file */ void setOutputFilename( std::string fn ) { mFwdConfig.set( "Output:url", fn ); } - /**@brief Set the data source for FTT hits - * + /** @brief Set the data source for FTT hits + * * @param source : {DATA, GEANT}, DATA means read from StEvent, GEANT means read directly from the GEANT hits */ void setFttHitSource( std::string source ) { mFwdConfig.set( "Source:ftt", source ); } - - /**@brief Enable or disable the Fst Rasterizer + + /** @brief Enable or disable the Fst Rasterizer * @param use : if true, load FST hits from GEANT and raster them according to r, phi resolutions. */ void setUseFstRasteredGeantHits( bool use = true ){ mFwdConfig.set( "SiRasterizer:active", use ); } - /**@brief Set the resolution in R for rasterizing FST hits (from fast sim) + /** @brief Set the resolution in R for rasterizing FST hits (from fast sim) * Only used when the Rasterizer is enabled, which results from reading FST hits from GEANT * @param r : resolution in r (cm) */ void setFstRasterR( double r = 3.0 /*cm*/ ){ mFwdConfig.set( "SiRasterizer:r", r ); } - /**@brief Set the resolution in phi for rasterizing FST hits (from fast sim) + /** @brief Set the resolution in phi for rasterizing FST hits (from fast sim) * Only used when the Rasterizer is enabled, which results from reading FST hits from GEANT * @param phi : resolution in phi (rad) */ void setFstRasterPhi( double phi = 0.00409 /*2*pi/(12*128)*/ ){ mFwdConfig.set( "SiRasterizer:phi", phi ); } //Track Finding - /**@brief Use Ftt hits in the Seed Finding - * + /** @brief Use FST and Ftt hits (sequentially) in the Seed Finding - then merge tracks + * + */ + void setSeedFindingWithFstFttSequential() { mFwdConfig.set( "TrackFinder:source", "seq" ); } + /** @brief Use FST and Ftt hits (simultaneously) in the Seed Finding + * + */ + void setSeedFindingWithFstFttSimultaneous() { mFwdConfig.set( "TrackFinder:source", "sim" ); } + /** @brief Use Ftt hits in the Seed Finding + * */ void setSeedFindingWithFtt() { mFwdConfig.set( "TrackFinder:source", "ftt" ); } - /**@brief Use Fst hits in the Seed Finding - * + /** @brief Use Fst hits in the Seed Finding + * */ void setSeedFindingWithFst() { mFwdConfig.set( "TrackFinder:source", "fst" ); } - /**@brief Set the number of track finding iterations + /** @brief Set the number of track finding iterations * @param n : number of iterations to run */ void setSeedFindingNumInterations( int n = 1 ) { mFwdConfig.set("TrackFinder:nIterations", n); } - /**@brief Set the number of phi slices to split the track iterations into + /** @brief Set the number of phi slices to split the track iterations into * @param n : number of slices of equal size (2pi)/n */ void setSeedFindingNumPhiSlices( int n = 8 ) { mFwdConfig.set("TrackFinder.Iteration:nPhiSlices", n); } - /**@brief Set the connector distance for track finding + /** @brief Set the connector distance for track finding * @param d : distance between planes (1 = adjacent) */ void setSeedFindingConnectorDistance( int d = 1 ) { mFwdConfig.set( "TrackFinder.Connector:distance", d ); } - /**@brief Enable or disable the SubsetNN + /** @brief Enable or disable the SubsetNN * @param use : if true, enables the subsetNN which find the most compatible set of tracks without shared hits * if false, all tracks are reported regardless of shared hits */ void setSeedFindingUseSubsetNN( bool use = true ) { mFwdConfig.set( "TrackFinder.SubsetNN:active", use ); } - /**@brief Enable or disable the SubsetNN + /** @brief Enable or disable the SubsetNN * @param n : minimum number of hits on a track seed. Seeds with fewer hits are discarded */ void setSeedFindingMinHitsOnTrack( int n = 3 ) { mFwdConfig.set( "TrackFinder.SubsetNN:min-hits-on-track", n ); } - /**@brief Enable or disable the HitRemover + /** @brief Enable or disable the HitRemover * @param use : if true, enables the hit remover which removes any hits from the hitmap that were used in a track * if false, hits are not removed after each iteration */ void setSeedFindingUseHitRemover( bool use = true ) { mFwdConfig.set( "TrackFinder.HitRemover:active", use ); } - /**@brief Enable or disable the Truth Seed finding + /** @brief Enable or disable the Truth Seed finding * @param use : if true, use Mc info to group hits into track seeds * if false, seed finding uses options as in the case for data */ void setUseTruthSeedFinding( bool use = true ) { mFwdConfig.set( "TrackFinder:active", !use ); } // Track Fitting - /**@brief Turn off track fitting + /** @brief Turn off track fitting * Useful if you want to speed up the run but dont need fitting (testing seed finding) */ void setTrackFittingOff() { mFwdConfig.set( "TrackFitter:active", "false" ); } - /**@brief Enable / disable material effects + /** @brief Enable / disable material effects * Material effects in kalman filter */ void setFittingMaterialEffects( bool mat = true) { mFwdConfig.set( "TrackFitter:materialEffects", mat ); } - /**@brief Set the resolution for the Primary Vertex in XY + /** @brief Set the resolution for the Primary Vertex in XY * @params sXY : sigma in XY (cm) */ void setPrimaryVertexSigmaXY( double sXY ) { mFwdConfig.set( "TrackFitter.Vertex:sigmaXY", sXY ); } - /**@brief Set the resolution for the Primary Vertex in Z + /** @brief Set the resolution for the Primary Vertex in Z * @params sZ : sigma in Z (cm) */ void setPrimaryVertexSigmaZ( double sZ ) { mFwdConfig.set( "TrackFitter.Vertex:sigmaZ", sZ ); } // TODO: add options for beamline constraint - /**@brief Include or exclude the Primary Vertex in fit + /** @brief Include or exclude the Primary Vertex in fit * @param pvf : if true, use PRimary Vertex in fit */ void setIncludePrimaryVertexInFit( bool pvf = true ) { mFwdConfig.set( "TrackFitter.Vertex:includeInFit", pvf ); } - /**@brief Set B-field to zero (for zero field running) + /** @brief Set B-field to zero (for zero field running) * @param zeroB : if true, use Zero B field */ void setZeroB( bool zeroB = true ) { mFwdConfig.set( "TrackFitter:zeroB", zeroB ); } - /**@brief Set B-field to constant (even outside of TPC) + /** @brief Set B-field to constant (even outside of TPC) * @param constB : if true, use const 0.5T B field */ void setConstB( bool constB = true ) { mFwdConfig.set( "TrackFitter:constB", constB ); } - /**@brief Force the use of McSeed for fit + /** @brief Force the use of McSeed for fit * @param mcSeed : if true, use mc momentum as the seed for the track fitter */ void setUseMcSeedForFit( bool mcSeed = true ) { mFwdConfig.set( "TrackFitter:mcSeed", mcSeed ); } - /**@brief Sets the tracking to refit + /** @brief Sets the tracking to refit * This adds compatible hits from whichever detector was NOT used in seed finding * if FTT seeding -> project to and add FST hits * if FST seeding -> project to and add FTT hits @@ -331,28 +301,81 @@ class StFwdTrackMaker : public StMaker { */ void setTrackRefit( bool refit = true) { mFwdConfig.set( "TrackFitter:refit", refit ); } - /**@brief Sets the maximum number of hits that can be considered failed before the entire track fit fails + /** @brief Sets the maximum number of hits that can be considered failed before the entire track fit fails * @param n : number of failed hits allowed, -1 = no limit */ void setMaxFailedHitsInFit( int n = -1 /*no lim*/ ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MaxFailedHits", n);} - /**@brief Sets Fitter debug level + /** @brief Sets Fitter debug level * @param level : 0 = no output, higher numbers are more verbose */ void setFitDebugLvl( int level = 0 /*0=no output*/ ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:DebugLvl", level); } - /**@brief Sets Max fit iterations before failing + /** @brief Sets Max fit iterations before failing * @param n : num iterations */ void setFitMaxIterations( int n=4 ) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MaxIterations", n); } - /**@brief Sets Min fit iterations before converging + /** @brief Sets Min fit iterations before converging * @param n : num iterations */ void setFitMinIterations( int n = 1) {mFwdConfig.set("TrackFitter.KalmanFitterRefTrack:MinIterations", n); } - /**@brief Enables smearing of the MC Primary Vertex according to sigmaXY,Z - * @param pvs : if true, smear vertex + /** @brief Enables smearing of the MC Primary Vertex according to sigmaXY,Z + * @param pvs : if true, smear vertex */ void setSmearMcPrimaryVertex( bool pvs = true ) { mFwdConfig.set( "TrackFitter.Vertex:smearMcVertex", pvs ); } - + + /** + * @brief Sets geometry cache filename + * + */ + void setGeoCache( TString gc ) { mGeoCache = gc; } + + /** + * @brief Set a generic Key Value in the Config object + * + * @param k key: any string representing absolute path e.g. `the.path.to.node:attribute` + * @param v value: value encoded as a string + */ + void setConfigKeyValue( std::string k, std::string v ){ + mFwdConfig.set( k, v ); + } + + /** @brief Sets a criteria value in the config for 2-hit criteria + * @param string name: name of the crit2, e.g. Crit2_RZRatio + * @param double min: minimum for the criteria, meaning depends on specific crit2 + * @param double max: maximum for the criteria, meaning depends on specific crit2 + */ + void setCrit2( std::string name, double min, double max ){ + for ( auto p : mFwdConfig.childrenOf( "TrackFinder.Iteration.SegmentBuilder" ) ){ + auto nName = mFwdConfig.get( p + ":name", "DNE" ); + if (nName == name) { + LOG_DEBUG << "Setting Crit2=" << nName << " (min=" << min << ", max=" << max << ")" << endm; + mFwdConfig.set(p + ":min", min ); + mFwdConfig.set(p + ":max", max ); + return; + } + } // loop on existing crit2 + // if we got here then the crit did not exist + + } + + /** @brief Sets a criteria value in the config for 3-hit criteria + * @param string name: name of the crit3, e.g. Crit2_RZRatio + * @param double min: minimum for the criteria, meaning depends on specific crit2 + * @param double max: maximum for the criteria, meaning depends on specific crit2 + */ + void setCrit3( std::string name, double min, double max ){ + for ( auto p : mFwdConfig.childrenOf( "TrackFinder.Iteration.ThreeHitSegments" ) ){ + auto nName = mFwdConfig.get( p + ":name", "DNE" ); + if (nName == name) { + LOG_DEBUG << "Setting Crit3=" << nName << " (min=" << min << ", max=" << max << ")" << endm; + mFwdConfig.set(p + ":min", min ); + mFwdConfig.set(p + ":max", max ); + return; + } + } // loop on existing crit3 + // if we got here then the crit did not exist + } + }; #endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h b/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h new file mode 100644 index 00000000000..bc608886d1b --- /dev/null +++ b/StRoot/StFwdTrackMaker/include/Tracker/FitterUtils.h @@ -0,0 +1,144 @@ +#ifndef FITTERUTILS_H +#define FITTERUTILS_H + +#include "GenFit/KalmanFitter.h" +#include "GenFit/KalmanFitterInfo.h" +#include "GenFit/KalmanFitterRefTrack.h" +#include "GenFit/MaterialEffects.h" +#include "GenFit/PlanarMeasurement.h" +#include "GenFit/RKTrackRep.h" +#include "GenFit/SpacepointMeasurement.h" +#include "GenFit/StateOnPlane.h" +#include "GenFit/TGeoMaterialInterface.h" +#include "GenFit/Track.h" +#include "GenFit/TrackPoint.h" + +#include "TVector3.h" + + +class FitSeedMaker { + public: + FitSeedMaker() {} + virtual ~FitSeedMaker() {} + virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) = 0; +}; +class ConstFitSeeder : public FitSeedMaker { + public: + ConstFitSeeder() {} + virtual ~ConstFitSeeder() {} + virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) { + posSeed.SetXYZ(0,0,0); + momSeed.SetXYZ(0,0,10); + q = 1; + } +}; +class GenericFitSeeder : public FitSeedMaker { + public: + GenericFitSeeder() {} + virtual ~GenericFitSeeder() {} + // Simple function to calculate the determinant of a 2x2 matrix + inline double determinant(double a, double b, double c, double d) { + return a * d - b * c; + } + struct Point { + double x, y; + }; + // Function to compute the curvature of a circle given 3 points + double computeSignedCurvature(const Point& p1, const Point& p2, const Point& p3) { + // Calculate the lengths of the sides of the triangle + double A = std::sqrt(std::pow(p2.x - p1.x, 2) + std::pow(p2.y - p1.y, 2)); + double B = std::sqrt(std::pow(p3.x - p2.x, 2) + std::pow(p3.y - p2.y, 2)); + double C = std::sqrt(std::pow(p1.x - p3.x, 2) + std::pow(p1.y - p3.y, 2)); + + // Calculate the determinant of the matrix formed by the points + double det = determinant(p2.x - p1.x, p2.y - p1.y, p3.x - p1.x, p3.y - p1.y); + // LOG_INFO << "Det: " << det << endm; + double charge = det > 0 ? -1 : 1; + // Area of the triangle formed by the three points + double area = std::abs(det) / 2.0; + + if (area == 0) { + std::cerr << "The points are collinear, curvature is undefined." << std::endl; + return -1; // Curvature is undefined for collinear points + } + + // Calculate the radius of the circumcircle using the formula: + // R = (A * B * C) / (4 * area) + double radius = (A * B * C) / (4 * area); + // LOG_INFO << "Radius: " << radius << endm; + // Curvature is the inverse of the radius + return charge / radius; + } + // Function to compute the average curvature for all combinations of 3 points + double averageCurvature( const Seed_t points ) { + // const std::vector& points; + int numPoints = points.size(); + if (numPoints < 3) { + std::cerr << "Not enough points to form a circle." << std::endl; + return -1; + } + + double totalCurvature = 0.0; + int validCombinations = 0; + + // Iterate over all combinations of 3 points + for (int i = 0; i < numPoints - 2; ++i) { + for (int j = i + 1; j < numPoints - 1; ++j) { + for (int k = j + 1; k < numPoints; ++k) { + Point p0 = {points[i]->getX(), points[i]->getY()}; + Point p1 = {points[j]->getX(), points[j]->getY()}; + Point p2 = {points[k]->getX(), points[k]->getY()}; + double curvature = computeSignedCurvature(p0, p1, p2); + if (curvature != -1) { // Exclude invalid (collinear) combinations + totalCurvature += curvature; + ++validCombinations; + } + } + } + } + + if (validCombinations == 0) { + std::cerr << "No valid curvature calculations possible." << std::endl; + return -1; // No valid triangles were found + } + + return totalCurvature / validCombinations; + } + + template int sgn(T val) { + return (T(0) < val) - (val < T(0)); + } + virtual void makeSeed(Seed_t seed, TVector3 &posSeed, TVector3 &momSeed, int &q ) { + const double qc = averageCurvature(seed); + posSeed.SetXYZ(0,0,0); + momSeed.SetXYZ(0,0,10); + + const double BStrength = 0.5; // 0.5 T + const double C = 0.3 * BStrength; //C depends on the units used for momentum and Bfield (here GeV and Tesla) + const double K = 0.00029979; // K depends on the units used for Bfield and momentum (here Gauss and GeV) + double pt = fabs((K*5)/qc); // pT from average measured curv + + // set the momentum seed's transverse momentum + momSeed.SetPerp(pt); + // compute the seed's eta from seed points + TVector3 p0 = TVector3(seed[0]->getX(), seed[0]->getY(), seed[0]->getZ()); + TVector3 p1 = TVector3(seed[1]->getX(), seed[1]->getY(), seed[1]->getZ()); + double dx = (p1.X() - p0.X()); + double dy = (p1.Y() - p0.Y()); + double dz = (p1.Z() - p0.Z()); + double phi = TMath::ATan2(dy, dx); + double Rxy = sqrt(dx * dx + dy * dy); + double theta = TMath::ATan2(Rxy, dz); + if (abs(dx) < 1e-6 || abs(dy) < 1e-6){ + phi = TMath::ATan2( p1.Y(), p1.X() ); + } + + // momSeed.SetPhi(phi); + // momSeed.SetTheta(theta); + + // assign charge based on sign of curvature + q = sgn(qc); + } +}; + +#endif \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h index c26fabd95ae..a94eeca9f4d 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdDataSource.h @@ -32,27 +32,11 @@ class FwdDataSource { // Cleanup void clear() { - - // delete the hits from the hitmap - for ( auto kv : mFttHits ){ - for ( auto h : kv.second ){ - delete h; - } - kv.second.clear(); - } - - for ( auto kv : mFstHits ){ - for ( auto h : kv.second ){ - delete h; - } - kv.second.clear(); - } - - // the tracks are shared pointers, so they will be taken care of by clearing the map (below) - - mFttHits.clear(); - mFstHits.clear(); - mMcTracks.clear(); + // Just empty our vectors, we dont own the memory + mFttHits.clear(); + mFstHits.clear(); + // the tracks are shared pointers, so they will be taken care of by clearing the map (below) + mMcTracks.clear(); } // TODO, protect and add interaface for pushing hits / tracks diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h index 93e6de702b7..9d928fa7457 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdGeomUtils.h @@ -9,13 +9,19 @@ class FwdGeomUtils { public: + + FwdGeomUtils( TGeoManager * gMan ) { - if ( gMan != nullptr ) + if ( gMan != nullptr ){ _navigator = gMan->AddNavigator(); + _gMan = gMan; + } } ~FwdGeomUtils(){ - + if ( _gMan != nullptr && _navigator != nullptr){ + _gMan->RemoveNavigator( _navigator ); + } } bool cd( const char* path ){ @@ -43,11 +49,11 @@ class FwdGeomUtils { } double fttZ( int index ) { - // This ftt_z_delta is needed to match the z location of hits (midpint of active volume?) to the z location of the mother volume. + // This ftt_z_delta is needed to match the z location of hits (midpint of active volume?) to the z location of the mother volume. // NOTE: It may be possible to improve this when the higher precision FTT geometry model is added const double ftt_z_delta = -0.5825245; stringstream spath; - spath << "/HALL_1/CAVE_1/STGM_1/STFM_" << (index + 1) * 4 << "/"; + spath << "/HALL_1/CAVE_1/STGM_1/STFM_" << (index + 1) * 4 << "/"; bool can = cd( spath.str().c_str() ); if ( can && _matrix != nullptr ){ return _matrix->GetTranslation()[2] + ftt_z_delta; @@ -69,12 +75,12 @@ class FwdGeomUtils { // the index are now 4,5,6 // hence +4 below // also fixed typo, previously was incorrectly FTSD_ - + const double z_delta = 1.755; stringstream spath; - spath << "/HALL_1/CAVE_1/FSTM_1/FSTD_" << (index + 4) << "/"; + spath << "/HALL_1/CAVE_1/FSTM_1/FSTD_" << (index + 4) << "/"; bool can = cd( spath.str().c_str() ); if ( can && _matrix != nullptr ){ - return _matrix->GetTranslation()[2]; + return _matrix->GetTranslation()[2] + z_delta; } return 0.0; } @@ -85,6 +91,7 @@ class FwdGeomUtils { TGeoHMatrix *_matrix = nullptr; TGeoIterator *_iter = nullptr; TGeoNavigator *_navigator = nullptr; + TGeoManager *_gMan = nullptr; }; -#endif \ No newline at end of file +#endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h index bcf4cb1fa7b..bc44ea71548 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdHit.h @@ -11,6 +11,8 @@ #include #include +#include "StEvent/StEnumerations.h" + class StHit; class FwdSystem : public KiTrack::ISectorSystem { @@ -20,7 +22,7 @@ class FwdSystem : public KiTrack::ISectorSystem { static const int sNFstLayers = 3; FwdSystem(const int ndisks = FwdSystem::sNFwdLayers) : KiTrack::ISectorSystem(), mNDisks(ndisks){}; ~FwdSystem(){/* */}; - virtual unsigned int getLayer(int diskid) const throw(KiTrack::OutOfRange) { + virtual unsigned int getLayer(int diskid) const { return diskid; } @@ -50,14 +52,14 @@ class McTrack { mStartVertex = start_vertex; } - void addHit(KiTrack::IHit *hit) { mHits.push_back(hit); } - // void addFstHit(KiTrack::IHit *hit) { mFstHits.push_back(hit); } + void addFttHit(KiTrack::IHit *hit) { mFttHits.push_back(hit); } + void addFstHit(KiTrack::IHit *hit) { mFstHits.push_back(hit); } double mPt, mEta, mPhi; int mTid, mQ, mStartVertex; - std::vector mHits; - // std::vector mFstHits; + std::vector mFttHits; + std::vector mFstHits; }; @@ -67,13 +69,28 @@ class McTrack { */ class FwdHit : public KiTrack::IHit { public: - FwdHit(unsigned int id, float x, float y, float z, int vid, int tid, - TMatrixDSym covmat, std::shared_ptr mcTrack = nullptr ) + // Default ctor + FwdHit() : KiTrack::IHit() { + _id = 0; + _x = 0; + _y = 0; + _z = 0; + _detid = 0; + _tid = 0; + _vid = 0; + _sector = 0; + _mcTrack = nullptr; + _hit = 0; + _covmat.ResizeTo( 3, 3 ); + }; + FwdHit(unsigned int id, float x, float y, float z, int vid, int detid, int tid, + TMatrixDSym covmat, std::shared_ptr mcTrack ) : KiTrack::IHit() { _id = id; _x = x; _y = y; _z = z; + _detid = detid; _tid = tid; _vid = vid; _mcTrack = mcTrack; @@ -94,13 +111,29 @@ class FwdHit : public KiTrack::IHit { } }; + // Set basic props for e.g. Primary Vertex type hits + void setXYZDetId( float x, float y, float z, int detid ){ + _x = x; + _y = y; + _z = z; + _detid = detid; + } + + bool isFst() const { return _detid == kFstId; } + bool isFtt() const { return _detid == kFttId; } + bool isPV() const { return _detid == kTpcId; } + + std::shared_ptr getMcTrack() { return _mcTrack; } + const KiTrack::ISectorSystem *getSectorSystem() const { return FwdSystem::sInstance; } + void setSector( int s ){ _sector = s; } int getTrackId() { return _tid;} int _tid; // aka ID truth int _vid; // volume id + int _detid; // detector id unsigned int _id; // just a unique id for each hit in this event. std::shared_ptr _mcTrack; TMatrixDSym _covmat; @@ -108,7 +141,8 @@ class FwdHit : public KiTrack::IHit { StHit *_hit; }; -using Seed_t = std::vector; +// Track Seed typdef +typedef std::vector Seed_t; class FwdConnector : public KiTrack::ISectorConnector { public: diff --git a/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h b/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h index 1316f9eca61..531faf43eeb 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/FwdTracker.h @@ -10,18 +10,18 @@ #include "TRandom3.h" #include "TTree.h" #include "TVector3.h" +#include "TLorentzVector.h" #include #include #include #include #include +#include #include "StFwdTrackMaker/include/Tracker/FwdHit.h" #include "StFwdTrackMaker/include/Tracker/FwdDataSource.h" -#include "StFwdTrackMaker/include/Tracker/QualityPlotter.h" #include "StFwdTrackMaker/include/Tracker/TrackFitter.h" -#include "StFwdTrackMaker/include/Tracker/BDTCriteria.h" #include "Criteria/Criteria.h" #include "Criteria/ICriterion.h" @@ -41,7 +41,7 @@ struct MCTruthUtils { static int dominantContribution(Seed_t hits, double &qa) { - + // track_id, hits on track std::unordered_map truth; for ( auto hit : hits ) { @@ -49,6 +49,10 @@ struct MCTruthUtils { truth[ fhit->_tid ]++; } + if ( truth.size() == 0 ){ + return -1; + } + using namespace std; using P = decltype(truth)::value_type; auto dom = max_element(begin(truth), end(truth), [](P a, P b){ return a.second < b.second; }); @@ -57,139 +61,222 @@ struct MCTruthUtils { // vote the same way on the track if ( hits.size() > 0 ) qa = double(dom->second) / double(hits.size()) ; - else + else qa = 0; return dom->first; }; }; +class EventStats { + public: + TString classname() const { return "EventStats"; } + void reset(){ + mNumSeeds = 0; + mAttemptedFits = 0; + mFailedFits = 0; + mGoodFits = 0; + mGoodCardinals = 0; + + mAttemptedReFits = 0; + mFailedReFits = 0; + mGoodReFits = 0; + mPossibleReFit = 0; + + mNumFwdVertices = 0; + mAttemptedPrimaryFits = 0; + mGoodPrimaryFits = 0; + mFailedPrimaryFits = 0; + + mStep1Duration.clear(); + mStep2Duration.clear(); + mStep3Duration.clear(); + mStep4Duration.clear(); + mFitDuration.clear(); + } + int mNumSeeds = 0; + int mAttemptedFits = 0; + int mFailedFits = 0; + int mGoodFits = 0; + int mGoodCardinals = 0; + + int mAttemptedReFits = 0; + int mFailedReFits = 0; + int mGoodReFits = 0; + int mPossibleReFit = 0; + + int mNumFwdVertices = 0; + int mAttemptedPrimaryFits = 0; + int mGoodPrimaryFits = 0; + int mFailedPrimaryFits = 0; + vector mStep1Duration; + vector mSeedFindingDuration; + vector mStep2Duration; + vector mStep3Duration; + vector mStep4Duration; + vector mFitDuration; +}; + class GenfitTrackResult { public: - GenfitTrackResult( size_t nFTT, size_t nFST, - Seed_t &seedTrack, genfit::Track *track ) { - this->nFST = nFST; - this->nFTT = nFTT; - this->trackSeed = seedTrack; - + GenfitTrackResult(){} + GenfitTrackResult( Seed_t &seed, std::shared_ptr track ) { + set( seed, track ); + } + ~GenfitTrackResult(){ + // Clear(); + } + void Clear() { + if ( mTrack ){ + mTrack->Clear(); + } + } + void set( Seed_t &seeds, std::shared_ptr track ){ + setSeed( seeds ); + setTrack( track ); + } + void setSeed( Seed_t &seed ){ + mSeed = seed; + mIdTruth = MCTruthUtils::dominantContribution( seed, mQaTruth ); + LOG_INFO << "GenFitTrackResult::mIdTruth = " << mIdTruth << ", QaTruth = " << mQaTruth << endm; + } + void setTrack( std::shared_ptr track ){ try { - this->track = track; - this->status = *(this->track->getFitStatus()); - this->trackRep = this->track->getCardinalRep(); - - this->isFitConverged = this->status.isFitConverged(); - this->isFitConvergedFully = this->status.isFitConvergedFully(); - this->isFitConvergedPartially = this->status.isFitConvergedPartially(); - this->nFailedPoints = this->status.getNFailedPoints(); - this->charge = this->status.getCharge(); - - this->nPV = this->track->getNumPoints() - (nFTT + nFST); - - this->momentum = this->trackRep->getMom( this->track->getFittedState(0, this->trackRep) ); + // this->track = new genfit::Track(*track); + mTrack = track; + mTrack ->setMcTrackId(mIdTruth); + mStatus = mTrack->getFitStatus(); + mTrackRep = mTrack->getCardinalRep(); + + mIsFitConverged = mStatus->isFitConverged(); + mIsFitConvergedFully = mStatus->isFitConvergedFully(); + mIsFitConvergedPartially = mStatus->isFitConvergedPartially(); + mNFailedPoints = mStatus->getNFailedPoints(); + mCharge = mStatus->getCharge(); + mChi2 = mStatus->getChi2(); + + if ( mIsFitConverged ){ + LOG_INFO << "GTR Setting momentum from track" << endm; + mMomentum = mTrackRep->getMom( mTrack->getFittedState(0, mTrackRep) ); + } LOG_DEBUG << "GenfitTrackResult::set Track successful" << endm; - } catch ( genfit::Exception &e ) { - LOG_ERROR << "GenfitTrackResult cannot get track" << endm; - this->track = nullptr; - this->trackRep = nullptr; - - this->isFitConverged = false; - this->isFitConvergedFully = false; - this->isFitConvergedPartially = false; - this->nFailedPoints = nFST + nFTT; - this->charge = 0; + LOG_ERROR << "Unable to set track -> GenfitException: " << e.what() << endm; + this->mTrack = nullptr; + this->mTrackRep = nullptr; + + this->mIsFitConverged = false; + this->mIsFitConvergedFully = false; + this->mIsFitConvergedPartially = false; + this->mNFailedPoints = 99; + this->mCharge = 0; + this->mChi2 = -1; } } - ~GenfitTrackResult() { - // MEMORY LEAK - // LOG_INFO << "~GenfitTrackResult" << endm; - // if (this->track) - // delete this->track; - // this->track = nullptr; - } - - void setFst( Seed_t &seedFst, genfit::Track *track ){ - LOG_DEBUG << "GenfitTrackResult::setFSt" << endm; - nFST = seedFst.size(); - fstSeed = seedFst; - - try { - this->fstTrack = new genfit::Track(*track); - // make sure the McTrackId is set correctly - this->fstTrack->setMcTrackId( this->track->getMcTrackId() ); - this->fstStatus = *(this->fstTrack->getFitStatus()); - this->fstTrackRep = this->fstTrack->getCardinalRep(); - - this->isFitConverged = this->fstStatus.isFitConverged(); - this->isFitConvergedFully = this->fstStatus.isFitConvergedFully(); - this->isFitConvergedPartially = this->fstStatus.isFitConvergedPartially(); - this->nFailedPoints = this->fstStatus.getNFailedPoints(); - this->charge = this->fstStatus.getCharge(); - this->fstMomentum = this->fstTrackRep->getMom( this->fstTrack->getFittedState(0, this->fstTrackRep) ); + /** @brief Set the DCA and primary vertex for the event + * + */ + void setDCA( TVector3 pv ){ + mPV = pv; + if ( mTrack ){ + try { + auto dcaState = mTrack->getFittedState( 0 ); + this->mTrackRep->extrapolateToPoint( dcaState, mPV ); + this->mDCA = dcaState.getPos(); + } catch ( genfit::Exception &e ) { + LOG_ERROR << "CANNOT GET DCA : GenfitException: " << e.what() << endm; + this->mDCA = TVector3(99,99,99); + } - } catch ( genfit::Exception &e ) { - LOG_ERROR << "CANNOT GET FST TRACK" << endm; - this->fstTrack = nullptr; - this->fstTrackRep = nullptr; - - this->fstIsFitConverged = false; - this->fstIsFitConvergedFully = false; - this->fstIsFitConvergedPartially = false; - this->fstNFailedPoints = nFST + nFTT; - this->fstCharge = 0; } } + size_t numFtt() const { + size_t n = 0; + for ( auto hit : mSeed ){ + if ( dynamic_cast(hit)->_detid == kFttId ){ + n++; + } + } + return n; + } + size_t numFst() const { + size_t n = 0; + for ( auto hit : mSeed ){ + if ( dynamic_cast(hit)->_detid == kFstId ){ + n++; + } + } + return n; + } + size_t numPV() const { + size_t n = 0; + for ( auto hit : mSeed ){ + if ( dynamic_cast(hit)->isPV() ){ + n++; + } + } + return n; + } - Seed_t trackSeed; - Seed_t fstSeed; - TVector3 momentum; - double charge; - size_t nFST = 0; - size_t nFTT = 0; - size_t nPV = 0; - genfit::FitStatus status; - genfit::AbsTrackRep *trackRep = nullptr; - genfit::Track *track = nullptr; - bool isFitConverged = false; - bool isFitConvergedFully = false; - bool isFitConvergedPartially = false; - size_t nFailedPoints = 0; - - // Result after FST refit - genfit::Track *fstTrack = nullptr; - genfit::AbsTrackRep *fstTrackRep = nullptr; - genfit::FitStatus fstStatus; - bool fstIsFitConverged = false; - bool fstIsFitConvergedFully = false; - bool fstIsFitConvergedPartially = false; - size_t fstNFailedPoints = 0; - double fstCharge = 0; - TVector3 fstMomentum; - - void summary() { - LOG_INFO << TString::Format( "TrackResult[p=(%f, %f, %f)/(%f, %f, %f), q=%f, nFTT=%lu, nFST=%lu, nPV=%lu, isFitConvergedFully=%d]", momentum.X(), momentum.Y(), momentum.Z(), momentum.Pt(), momentum.Eta(), momentum.Phi(), charge, nFTT, nFST, nPV, isFitConvergedFully ).Data() << endm; + void mergeSeeds( GenfitTrackResult &other ){ + // combine the unique Ftt and Fst seeds + for ( auto hit : other.mSeed ){ + if ( std::find( mSeed.begin(), mSeed.end(), hit ) == mSeed.end() ){ + mSeed.push_back( hit ); + } + } } -}; + + bool isPrimary = false; + Seed_t mSeed; + TVector3 mPV; // as a TVector3 + TVector3 mMomentum; + float mCharge = 0; + float mChi2 = -1; + genfit::FitStatus *mStatus = nullptr; + genfit::AbsTrackRep *mTrackRep = nullptr; + std::shared_ptr mTrack = nullptr; + bool mIsFitConverged = false; + bool mIsFitConvergedFully = false; + bool mIsFitConvergedPartially = false; + size_t mNFailedPoints = 0; + TVector3 mDCA; + int mIdTruth = -1; + double mQaTruth = 0; +}; // GenfitTrackResult class ForwardTrackMaker { public: ForwardTrackMaker() : mConfigFile("config.xml"), mEventVertex(-999, -999, -999) { // noop } - + const std::vector &getTrackResults() const { return mTrackResults; } - const std::vector &getRecoTracks() const { return mRecoTracks; } - const std::vector &getFitMomenta() const { return mFitMoms; } - const std::vector &getNumFstHits() const { return mNumFstHits; } - const std::vector &getFitStatus() const { return mFitStatus; } - const std::vector &globalTrackReps() const { return mGlobalTrackReps; } - const std::vector &globalTracks() const { return mGlobalTracks; } + const std::vector &getTrackSeeds() const { return mTrackSeeds; } + const EventStats &getEventStats() const { return mEventStats; } + + void Clear(){ + for ( auto gtr : mTrackResults ){ + gtr.Clear(); + } + mTrackResults.clear(); + } + /** + * @brief Set the Config File object + * + * @param cf : config filename + */ void setConfigFile(std::string cf) { mConfigFile = cf; } + /** + * @brief Set the Save Criteria Values object + * + * @param save : true to save crit values + */ void setSaveCriteriaValues(bool save) { mSaveCriteriaValues = save; } @@ -199,44 +286,26 @@ class ForwardTrackMaker { // Adopt external hit loader void setData(std::shared_ptrdata) { mDataSource = data; } + /** + * @brief Initialize FwdTracker + * + * @param geoCache : name of cached geometry file + * @param genHistograms : generate histograms + */ virtual void initialize( TString geoCache, bool genHistograms) { - mGenHistograms = genHistograms; - if (mGenHistograms) setupHistograms(); - mGeoCache = geoCache; - mDoTrackFitting = !(mConfig.get("TrackFitter:off", false)); + mDoTrackFitting = mConfig.get("TrackFitter:active", true); if (!mConfig.exists("TrackFitter")) mDoTrackFitting = false; - } - - - void writeEventHistograms() { - - // no file, dont write anything - if ( !gDirectory ) - return; + } //initialize - gDirectory->cd(); - // write out the config we use (do before histos): - TNamed n("mConfig", mConfig.dump()); - n.Write(); - - writeHistograms(); - - gDirectory->mkdir("Fit/"); - gDirectory->cd("Fit/"); - mTrackFitter->writeHistograms(); - gDirectory->cd(""); - mQualityPlotter->writeHistograms(); - } - - /** Loads Criteria from XML configuration. - * - * Utility function for loading criteria from XML config. - * - * @return vector of ICriterion pointers - */ + /** + * @brief Loads Criteria from XML configuration. + * Utility function for loading criteria from XML config. + * @param path : path in config to load + * @return vector of ICriterion pointers + */ std::vector loadCriteria(string path) { std::vector crits; @@ -252,10 +321,11 @@ class ForwardTrackMaker { float vmin = mConfig.get(p + ":min", 0); float vmax = mConfig.get(p + ":max", 1); - + KiTrack::ICriterion * crit = nullptr; if ( name == "Crit2_BDT" ){ - crit = new BDTCrit2( vmin, vmax ); + // crit = new BDTCrit2( vmin, vmax ); + LOG_WARN << "BDT Criteria not implemented/out of date" << endm; } else { crit = KiTrack::Criteria::createCriterion(name, vmin, vmax); } @@ -266,12 +336,32 @@ class ForwardTrackMaker { crits.push_back(new CriteriaKeeper(crit)); // CriteriaKeeper intercepts values and saves them else crits.push_back(crit); - + } return crits; + } // loadCriteria + + /** + * @brief Clear the loaded criteria + * @param crits : vector of ICriterion pointers to properly clear + */ + void clearCriteria( std::vector &crits ){ + for ( size_t i = 0; i < crits.size(); i++ ){ + if ( crits[i] ){ + delete crits[i]; + crits[i] = nullptr; + } + } + crits.clear(); } + /** + * @brief Get the Criteria Values object + * + * @param crit_name : Criteria to get + * @return std::vector : list of values + */ std::vector getCriteriaValues(std::string crit_name) { std::vector em; if (mSaveCriteriaValues != true) { @@ -293,8 +383,14 @@ class ForwardTrackMaker { } return em; - }; + } //getCriteriaValues + /** + * @brief Get the Criteria All Values object + * + * @param crit_name : Criteria values to get + * @return std::vector> : map of values + */ std::vector> getCriteriaAllValues(std::string crit_name) { std::vector> em; if (mSaveCriteriaValues != true) { @@ -316,8 +412,14 @@ class ForwardTrackMaker { } return em; - }; + } // getCriteriaAllValues + /** + * @brief Get the Criteria Track Ids object + * + * @param crit_name : Name of criteria to get track ids for + * @return std::vector : list of track ids + */ std::vector getCriteriaTrackIds(std::string crit_name) { std::vector em; if (mSaveCriteriaValues != true) { @@ -339,8 +441,12 @@ class ForwardTrackMaker { } return em; - }; + } //getCriteriaTrackIds + /** + * @brief Clear the saved values for two hit and three hit criteria + * + */ void clearSavedCriteriaValues() { if (mSaveCriteriaValues != true) { return; @@ -355,103 +461,28 @@ class ForwardTrackMaker { auto critKeeper = static_cast(crit); critKeeper->clear(); } - } + } // clearSavedCriteria + /** + * @brief Determine the total num of hits in the hitmap + * + * @param hitmap : hitmap to consider + * @return size_t : total num of hits + */ size_t nHitsInHitMap(FwdDataSource::HitMap_t &hitmap) { size_t n = 0; - for (auto kv : hitmap) { n += kv.second.size(); } - - return n; - } - - size_t countRecoTracks(size_t nHits) { - size_t n = 0; - - for (auto t : mRecoTracks) { - if (t.size() == nHits) - n++; - } - return n; } - void setupHistograms() { - - mHist["input_nhits"] = new TH1I("input_nhits", ";# hits", 1000, 0, 1000); - mHist["nAttemptedFits"] = new TH1I("nAttemptedFits", ";;# attempted fits", 10, 0, 10); - mHist["nPossibleFits"] = new TH1I("nPossibleFits", ";;# possible fits", 10, 0, 10); - // refit with silicon - mHist["nPossibleReFits"] = new TH1I("nPossibleReFits", ";;# possible REfits", 10, 0, 10); - mHist["nAttemptedReFits"] = new TH1I("nAttemptedReFits", ";;#attempted REfits", 10, 0, 10); - mHist["nFailedReFits"] = new TH1I("nFailedReFits", ";;# failed REfits", 10, 0, 10); - - mHist["FitStatus"] = new TH1I("FitStatus", ";;# failed REfits", 15, 0, 15); - FwdTrackerUtils::labelAxis(mHist["FitStatus"]->GetXaxis(), {"Seeds", "AttemptFit", "GoodFit", "BadFit", "GoodCardinal", "PossibleReFit", "AttemptReFit", "GoodReFit", "BadReFit", "w3Si","w2Si", "w1Si", "w0Si" }); - - mHist["FitDuration"] = new TH1I("FitDuration", ";Duration (ms)", 5000, 0, 50000); - mHist["nSiHitsFound"] = new TH2I( "nSiHitsFound", ";Si Disk; n Hits", 5, 0, 5, 10, 0, 10 ); - - mHist["Step1Duration"] = new TH1I("Step1Duration", ";Duration (ms)", 500, 0, 500); - mHist["Step2Duration"] = new TH1I("Step2Duration", ";Duration (ms)", 500, 0, 500); - mHist["Step3Duration"] = new TH1I("Step3Duration", ";Duration (ms)", 500, 0, 500); - mHist["Step4Duration"] = new TH1I("Step4Duration", ";Duration (ms)", 500, 0, 500); - } - - void fillHistograms() { - - if (mGenHistograms && mDataSource != nullptr) { - auto hm = mDataSource->getFttHits(); - for (auto hp : hm) - mHist["input_nhits"]->Fill(hp.second.size()); - } - } - - void writeHistograms() { - if ( !mGenHistograms ){ - return; - } - - for (auto nh : mHist) { - nh.second->SetDirectory(gDirectory); - nh.second->Write(); - } - } - - // this is the main event loop. doEvent processes a single event iEvent... - void make() { - - int single_event = mConfig.get("Input:event", -1); - - if (single_event >= 0) { - doEvent(single_event); - return; - } - - unsigned long long firstEvent = mConfig.get("Input:first-event", 0); - - if (mConfig.exists("Input:max-events")) { - unsigned long long maxEvents = mConfig.get("Input:max-events", 0); - - if (nEvents > maxEvents) - nEvents = maxEvents; - - } - - // loop over events - - for (unsigned long long iEvent = firstEvent; iEvent < firstEvent + nEvents; iEvent++) { - doEvent(iEvent); - } - - if (mGenHistograms){ - mQualityPlotter->finish(); - writeEventHistograms(); - } - } - + /** + * @brief Remove used hits from the hit map + * + * @param hitmap : hitmap with hits used this round + * @param tracks : tracks formed from hits + */ void removeHits(FwdDataSource::HitMap_t &hitmap, std::vector &tracks) { for (auto track : tracks) { @@ -469,290 +500,557 @@ class ForwardTrackMaker { } // loop on track } // removeHits - void doEvent(unsigned long long int iEvent = 0) { + + /** @brief merges the FST and FTT hitmaps into a single hitmap + * The FTT hits are shifted by the number of FST sectors + * @param hitmap1: FST hitmap + * @param hitmap2: FTT hitmap + * @return void + */ + void mergeHitmaps( FwdDataSource::HitMap_t &hitmap1, FwdDataSource::HitMap_t &hitmap2 ){ + static const int numFstSectors = 3; + for ( auto kv : hitmap2 ){ + for ( auto hit : kv.second ){ + dynamic_cast( hit )->setSector( hit->getSector() + numFstSectors ); + hitmap1[kv.first + numFstSectors].push_back( hit ); + } + } + } // mergeHitmaps + + /** @brief cleanup the event-wise data structures + * + */ + void cleanup() { /************** Cleanup ****************************************/ // Moved cleanup to the start of doEvent, so that the fit results // persist after the call - mRecoTracks.clear(); - mRecoTrackQuality.clear(); - mRecoTrackIdTruth.clear(); - mFitMoms.clear(); - mNumFstHits.clear(); - mFitStatus.clear(); - - - // Clear pointers to the track reps from previous event - for (auto p : mGlobalTrackReps) - delete p; - - mGlobalTrackReps.clear(); - - // Clear pointers to global tracks - for (auto p : mGlobalTracks) - delete p; - - mGlobalTracks.clear(); - + mTrackSeeds.clear(); mTrackResults.clear(); + mEventStats.reset(); + mTotalHitsRemoved = 0; /************** Cleanup **************************/ + } - if (mGenHistograms ){ - mQualityPlotter->startEvent(); // starts the timer for this event + bool useMcTrackFinding(){ + /*************************************************************/ + // Determine if we should use MC seed finding + /*************************************************************/ + bool mcTrackFinding = true; + if (mConfig.exists("TrackFinder")){ + mcTrackFinding = false; } + if (mConfig.exists("TrackFinder") && mConfig.get( "TrackFinder:mc", false ) == false ){ + mcTrackFinding = false; + } + if (mConfig.exists("TrackFinder") && mConfig.get( "TrackFinder:active", true ) == false){ + mcTrackFinding = true; + } + return mcTrackFinding; + } - mTotalHitsRemoved = 0; - + /** + * @brief Perform the track finding + * Creates a list of track seeds from the hitmaps + * Retrieve them using `getTrackSeeds()` + */ + void findTrackSeeds() { + cleanup(); /*************************************************************/ - // Step 1 - // Load and sort the hits + // Get the hitmaps /*************************************************************/ long long itStart = FwdTrackerUtils::nowNanoSecond(); - FwdDataSource::HitMap_t &hitmap = mDataSource->getFttHits();; + FwdDataSource::HitMap_t &fttHitmap = mDataSource->getFttHits(); + FwdDataSource::HitMap_t &fstHitmap = mDataSource->getFstHits(); + + /*************************************************************/ + // Determine seed finding mode + /*************************************************************/ + string hitmapSource = mConfig.get("TrackFinder:source", "ftt"); + LOG_INFO << "Hitmap Source: " << hitmapSource << endm; + mSeedSource = kSeqSeed; // default to FST + if (hitmapSource == "fst") + mSeedSource = kFstSeed; + else if (hitmapSource == "ftt") + mSeedSource = kFttSeed; + else if (hitmapSource == "seq") + mSeedSource = kSeqSeed; + else if (hitmapSource == "sim") + mSeedSource = kSimSeed; + LOG_INFO << "Performing Fwd Seed finding with mode: " << mConfig.get("TrackFinder:source", "ftt") << " = " << mSeedSource << endm; FwdDataSource::McTrackMap_t &mcTrackMap = mDataSource->getMcTracks(); - fillHistograms(); long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) - mHist["Step1Duration"]->Fill( duration ); - - - bool mcTrackFinding = true; - - if (mConfig.exists("TrackFinder")) - mcTrackFinding = false; - /***********************************************/ - // MC Track Finding - if (mcTrackFinding) { - LOG_DEBUG << "MC TRACK FINDING " << endm; - doMcTrackFinding(mcTrackMap); + mEventStats.mStep1Duration.push_back( duration ); - /***********************************************/ - // REFIT with Silicon hits - if (mConfig.get("TrackFitter:refitSi", true)) { - addSiHitsMc(); - } else { - LOG_DEBUG << "Skipping FST Hits" << endm; - // skip Si refit - } - /***********************************************/ - - if (mConfig.get("TrackFitter:refitGBL", true)) { - for (size_t i = 0; i < mGlobalTracks.size(); i++) { - mTrackFitter->refitTrackWithGBL(mGlobalTracks[i]); - } - } - - if (mGenHistograms ){ - mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus); - } + /*************************************************************/ + // DO MC Track Finding (if set to do so) + if (useMcTrackFinding()) { + doMcTrackFinding(mcTrackMap, mSeedSource); + mEventStats.mNumSeeds = mTrackSeeds.size(); + long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + mEventStats.mSeedFindingDuration.push_back( duration2 ); return; + } else { + LOG_DEBUG << "Performing Standard Track Finding" << endm; } - /***********************************************/ + /*************************************************************/ - /***********************************************/ + /*************************************************************/ // Standard Track Finding - // plus initial fit size_t nIterations = mConfig.get("TrackFinder:nIterations", 0); for (size_t iIteration = 0; iIteration < nIterations; iIteration++) { - doTrackIteration(iIteration, hitmap); - } - /***********************************************/ + if ( mSeedSource == kSimSeed){ + mergeHitmaps( fstHitmap, fttHitmap ); + } else { + if ( mSeedSource == kFstSeed || mSeedSource == kSeqSeed ){ + doSeedFindingIteration(iIteration, fstHitmap); + } + if ( mSeedSource == kFttSeed || mSeedSource == kSeqSeed){ + doSeedFindingIteration(iIteration, fttHitmap); + } + } + } // iIteration + /*************************************************************/ + mEventStats.mNumSeeds = mTrackSeeds.size(); + long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + mEventStats.mSeedFindingDuration.push_back( duration2 ); + } // FindTrackSeeds - /***********************************************/ - // REFIT with Silicon hits - if (mConfig.get("TrackFitter:refitSi", true)) { - addSiHits(); - } else { - // Skipping Si Refit + + std::vector< genfit::GFRaveVertex * > findFwdVertices( const vector &globalTracks ){ + // we will return a vector of vertices + std::vector< genfit::GFRaveVertex * > raveVertices; + + + // The RAVE factory needs the (bare) track pointers for vertex finding + vector tracks; + for ( auto gtr : globalTracks ){ + if ( gtr.mTrack ){ + tracks.push_back( gtr.mTrack.get() ); + } } - /***********************************************/ - if ( mGenHistograms ){ - mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus); + bool useBeamConstraint = false; + if ( useBeamConstraint ){ + // TODO: load "official" beamline constraint parameters + TMatrixDSym bscm(3); + const double bssXY = 2.0; + bscm(0, 0) = bssXY*bssXY; + bscm(1, 1) = bssXY*bssXY; + bscm(2, 2) = 50.5 * 50.5; + mGFRVertices.setBeamspot( TVector3( 0, 0, 0 ), bscm ); } - } // doEvent - void fitTrack(Seed_t &track) { - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("Seeds", 1); + + mGFRVertices.findVertices( &raveVertices, tracks, useBeamConstraint ); + LOG_DEBUG << "raveVertices.size() = " << raveVertices.size() << endm; + for ( auto vert : raveVertices ){ + LOG_DEBUG << TString::Format( "GFRaveVertex vertex @(%f, %f, %f)\n\n", vert->getPos().X(), vert->getPos().Y(), vert->getPos().Z() ) << endm; + LOG_DEBUG << "GFRaveVertex\n"; + // LOG_DEBUG << "Position: "; vert->getPos().Print(); + // LOG_DEBUG << "Covariance: "; vert->getCov().Print(); + LOG_DEBUG << "Ndf: " << vert->getNdf() << ", Chi2: " << vert->getChi2() << ", Id: " << vert->getId() << "\n"; + LOG_DEBUG << "Number of tracks: " << vert->getNTracks() << "\n"; } + // if there is no Event Vertex, then we will use the first vertex found + // if ( raveVertices.size() > 0 ){ + // mEventVertex = raveVertices[0]->getPos(); + // // mEventVertexHit.setPos( mEventVertex ); + // } - // Calculate the MC info first and check filters - int idt = 0; - double qual = 0; - idt = MCTruthUtils::dominantContribution(track, qual); - - - TVector3 mcSeedMom; + return raveVertices; + } - auto mctm = mDataSource->getMcTracks(); - // get the MC track momentum if we can - if (mctm.count(idt)) { - auto mct = mctm[idt]; - mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); + /** + * @brief Perform a single fit from seed points + * + * @param seed : seed points from either FTT or FST + * @param includeVertex : include the primary vertex in the fit or not + * @return GenfitTrackResult : result of the fit + */ + GenfitTrackResult fitTrack(Seed_t &seed, TVector3 *momentumSeedState = nullptr) { + LOG_DEBUG << "FwdTracker::fitTrack->" << endm; + mEventStats.mAttemptedFits++; + // We will build this up as we go + GenfitTrackResult gtr; + + LOG_DEBUG << "--Setting seed on GenfitTrackResult, seed has " << seed.size() << " hits" << endm; + // First, set the seed information + gtr.setSeed( seed ); + + // If we are using a provided momentum state + if ( momentumSeedState ){ + LOG_DEBUG << "--FitTrack with provided momentum seed state" << endm; + mTrackFitter->fitTrack( seed, momentumSeedState ); + } else { + LOG_DEBUG << "--FitTrack without provided momentum seed state" << endm; + mTrackFitter->fitTrack( seed ); } + /*******************************************************/ + // Get the track from the fitter + // and set the track in the GenfitTrackResult + if (mTrackFitter->getTrack() != nullptr ){ + LOG_DEBUG << "--FitTrack found, setting seed and track only" << endm; + gtr.set( seed, mTrackFitter->getTrack() ); - // Mc Filter - bool bailout = false; - if (qual < mConfig.get("TrackFitter.McFilter:quality-min", 0.0)) { - bailout = true; - // LOG_INFO << "BAIL OUT on Fit bc quality = " << qual << endm; - } - if (mctm.count(idt)) { - auto mct = mctm[idt]; - mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); - if (mct->mPt < mConfig.get("TrackFitter.McFilter:pt-min", 0.0) || - mct->mPt > mConfig.get("TrackFitter.McFilter:pt-max", 1e10)) { - bailout = true; - // LOG_INFO << "BAIL OUT on Fit bc Pt = " << mct->mPt << endm; - } - if (mct->mEta < mConfig.get("TrackFitter.McFilter:eta-min", 0) || - mct->mEta > mConfig.get("TrackFitter.McFilter:eta-max", 1e10)) { - bailout = true; - // LOG_INFO << "BAIL OUT on Fit bc eta = " << mct->mEta << endm; + if (gtr.mStatus && gtr.mStatus->isFitConvergedFully()) { + mEventStats.mGoodFits++; + } else { + mEventStats.mFailedFits++; } - - } else { - // cannot find the track + } else { // set the track as a failed fit, but keep the seed info + LOG_DEBUG << "--FitTrack failed, setting seed only" << endm; + mEventStats.mFailedFits++; } + LOG_DEBUG << "<-FwdTracker::fitTrack complete" << endm; + return gtr; + } // fitTrack - bailout = false; - - TVector3 p; - p.SetPtEtaPhi( 0, -999, 0 ); - genfit::FitStatus fitStatus; - - genfit::AbsTrackRep *trackRep = nullptr;//new genfit::RKTrackRep(211); // pdg for pi+ - genfit::Track *genTrack = nullptr;//new genfit::Track( trackRep, TVector3(0, 0, 0), TVector3(0, 0, 0) ); + + /** + * @brief Loop on track seeds and fit each one + * + * Track fitting proceeds in 3 possible iterations + * 1. Fit seed points (without PV) + * 2. Look for additional hits in the other tracking detector + * 3. Refit the track with the additional hits + * 4. Refit the track with the primary vertex + * 5. look again and refit any additional hits + * + * @param trackSeeds : Track seeds + */ + void doTrackFitting( const std::vector &trackSeeds) { + LOG_DEBUG << ">>doTrackFitting" << endm; + if (!mDoTrackFitting) + return; + long long itStart = FwdTrackerUtils::nowNanoSecond(); - if (mDoTrackFitting && !bailout) { - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("AttemptFit", 1); + std::vector globalTracks; + std::vector primaryTracks; + + // Should we try to refit the track with aadditional points from other detectors? + const bool doRefit = mConfig.get("TrackFitter:refit", false); + LOG_INFO << "TrackFitter:refit = " << doRefit << endm; + + // Should we use the MC momentum as a seed for the fit? + const bool useMcSeedMomentum = mConfig.get("TrackFitter:mcSeed", false); + LOG_INFO << "TrackFitter:mcSeed = " << useMcSeedMomentum << endm; + + LOG_DEBUG << "Starting track fitting loop, mTrackResults.size() = " << mTrackResults.size() << endm; + LOG_DEBUG << "Starting Track fitting loop on " << trackSeeds.size() << " track seeds" << endm; + size_t index = 0; + for (auto t : trackSeeds) { + + GenfitTrackResult gtrGlobalRefit; // will store refit if needed + LOG_DEBUG << "\tTrack seed initial global fit #" << index << endm; + /***********************************************************************************************************/ + // Tracking Step 1 + // Fit each accepted track seed + + // If we are using MC momentum get it from associated track + TVector3 momentumSeedStateMc; + TVector3 *pMomSeedState = nullptr; + int idt = 0; + double qual = 0; + // Get the quality and MC truth id + idt = MCTruthUtils::dominantContribution(t, qual); + LOG_INFO << "\t\tMc Match idTruth=" << idt << ", quality = " << qual << endm; + if (true == useMcSeedMomentum) { + /*******************************************************/ + // Only for Simulation + // Calculate the MC info first and check filters + + auto mctm = mDataSource->getMcTracks(); + // get the MC track momentum if we can (may be used for state seed) + if (mctm.count(idt)) { + auto mct = mctm[idt]; + momentumSeedStateMc.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); + // pMomSeedState = &momentumSeedStateMc; + } else { + LOG_WARN << "\tRequested MC momentum for fit seed, but couldnt find MC Track for id: " << idt << ", qual: " << qual << endm; + } + /*******************************************************/ + } // else if pMomSeedState = nullptr, a seed momentum will be computed from seed points by tracker + + // Fit the track seed and get the GenfitTrackResult + GenfitTrackResult gtrGlobal = fitTrack(t, pMomSeedState); + gtrGlobal.setDCA( mEventVertex ); + + LOG_DEBUG << "\tFit track seed with " << gtrGlobal.mSeed.size() << " hits" << endm; + LOG_DEBUG << "\t\t McTrack Id = " << gtrGlobal.mIdTruth << ", QA = " << gtrGlobal.mQaTruth << endm; + // End Step 1 + /*******************************************************/ + + + // if the first fit fails then we cannot proceed with the refit steps + if (gtrGlobal.mIsFitConvergedPartially == false) { + LOG_WARN << "\tInitial fitting failed for seed " << index << endm; + LOG_DEBUG << "\tFitting failed for seed " << index << endm; + LOG_DEBUG << "\tSkipping the refit steps but saving the seed and failed fit" << endm; + globalTracks.push_back( gtrGlobal ); + index++; + continue; + // BREAK OUT OF THE LOOP } - - double vertex[3] = { mEventVertex.X(), mEventVertex.Y(), mEventVertex.Z() }; - - double * pVertex = 0; - if ( fabs(mEventVertex.X()) < 100 ){ - pVertex = vertex; // only use it if it has been set from default + if (doRefit == false) { + LOG_INFO << "\tRefit is disabled, saving the seed and initial fit" << endm; + gtrGlobal.isPrimary = false; + globalTracks.push_back( gtrGlobal ); + index++; + continue; + // BREAK OUT OF THE LOOP } - - if (true == mConfig.get("TrackFitter:mcSeed", false)) { - // use the MC pt, eta, phi as the seed for fitting - p = mTrackFitter->fitTrack(track, pVertex, &mcSeedMom); + /***********************************************************************************************************/ + // Tracking Step 2 + // Look for additional hits in the other tracking detector + // and add the new hits to the track + + // If requested, use the MC track finding to add hits to the track + if (useMcTrackFinding()) { + if (mSeedSource != kFttSeed) addFttHitsMc( gtrGlobal ); + if (mSeedSource != kFstSeed) addFstHitsMc( gtrGlobal ); + // globalTracks.push_back( gtrGlobalRefit ); + // index++; + // continue; // below is for "real" track finding only, for MC jump to next track } else { - // Normal case, real data - p = mTrackFitter->fitTrack(track, pVertex); - } - - if ( mGenHistograms ){ - if (p.Perp() > 1e-3) { - mHist["FitStatus"]->Fill("GoodFit", 1); - } else { - mHist["FitStatus"]->Fill("BadFit", 1); + // If we are not using MC track finding, + // then we will look for additional hits via projections + if (mSeedSource != kFttSeed){ // Look for FTT hits if it was not the original seed source + for ( int i = 0; i < FwdSystem::sNFttLayers; i++ ){ + addFttHits( gtrGlobal, i ); + } + } + if (mSeedSource != kFstSeed ){ // Look for FST hits if it was not the original seed source + for ( int i = 0; i < FwdSystem::sNFstLayers; i++ ){ + addFstHits( gtrGlobal, i ); + } } + // global refit + } + // End Step 2 + /***********************************************************************************************************/ + + /***********************************************************************************************************/ + // Tracking Step 3: Fit the new global track with additional hits + gtrGlobalRefit = fitTrack( gtrGlobal.mSeed, >rGlobal.mMomentum ); + gtrGlobalRefit.setDCA( mEventVertex ); + // End Step 3 + /***********************************************************************************************************/ + + /***********************************************************************************************************/ + // Tracking Step 4: Save the best global track result + GenfitTrackResult *activeTrack = >rGlobal; + if ( gtrGlobalRefit.mIsFitConvergedPartially ){ + activeTrack = >rGlobalRefit; } - - genTrack = new genfit::Track(*mTrackFitter->getTrack()); - genTrack->setMcTrackId(idt); - GenfitTrackResult gtr( track.size(), 0, track, genTrack ); - - // assign the fit results to be saved - fitStatus = mTrackFitter->getStatus(); - trackRep = mTrackFitter->getTrackRep()->clone(); // Clone the track rep - - if ( mGenHistograms && genTrack->getFitStatus(genTrack->getCardinalRep())->isFitConverged() && p.Perp() > 1e-3) { - mHist["FitStatus"]->Fill("GoodCardinal", 1); + if ( !activeTrack->mIsFitConvergedPartially ){ + // should not be possible according to above logic... + LOG_WARN << "\tFWD global track fit failed (both initial + refit)" << endm; + continue; } - // Save everything (now use GenfitTrackResult) - mFitMoms.push_back(p); - mGlobalTracks.push_back(genTrack); - mGlobalTrackReps.push_back(trackRep); - mFitStatus.push_back(fitStatus); - mRecoTrackQuality.push_back(qual); - mRecoTrackIdTruth.push_back(idt); - mNumFstHits.push_back(0); - - mTrackResults.push_back( gtr ); - - LOG_DEBUG << "FwdTracker::fitTrack complete" << endm; - } // if (mDoTrackFitting && !bailout) - } + // if the refit is successful, + // then we will add the track to the globalTracks + // if not keep the original global track + activeTrack->isPrimary = false; // should be default but just make sure + globalTracks.push_back( *activeTrack ); // save this global track result + // End Step 4 + /***********************************************************************************************************/ + } // loop on track seeds + + long long duration1 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + mEventStats.mFitDuration.push_back( duration1 ); + float perGood = (float) mEventStats.mGoodFits / (float) mEventStats.mAttemptedFits; + float perFailed = (float) mEventStats.mFailedFits / (float) mEventStats.mAttemptedFits; + float perCardinals = (float) mEventStats.mGoodCardinals / (float) mEventStats.mGoodFits; + LOG_DEBUG << "\tGlobal Track Fitting Results:" << + TString::Format( + "Attempts = %d, Good = %d (%f%%), Failed = %d (%f%%), GoodCardinals = %d (%f%%)", + mEventStats.mAttemptedFits, + mEventStats.mGoodFits, + perGood, + mEventStats.mFailedFits, + perFailed, + mEventStats.mGoodCardinals, + perCardinals ) << endm; + + const bool do_fwd_vertex_finding = true; + if (do_fwd_vertex_finding){ + /***********************************************************************************************************/ + // Step 5: Find the FWD Vertices + LOG_DEBUG << "\tStarting Track Fitting Step 3 (FWD Vertex Finding)" << endm; + auto fwdVertices = findFwdVertices( globalTracks ); + mEventStats.mNumFwdVertices = fwdVertices.size(); + + for ( auto vert : fwdVertices ){ + LOG_DEBUG << "\tFound FWD Vertex @(" << vert->getPos().X() << ", " << vert->getPos().Y() << ", " << vert->getPos().Z() << ")" << endm; + LOG_DEBUG << "\t\tvs mEventVertexHit: " << mEventVertexHit.getX() << ", " << mEventVertexHit.getY() << ", " << mEventVertexHit.getZ() << endm; + } - void doTrackFitting( std::vector &tracks) { - long long itStart = FwdTrackerUtils::nowNanoSecond(); - // Fit each accepted track seed - for (auto t : tracks) { - fitTrack(t); - } - long long itEnd = FwdTrackerUtils::nowNanoSecond(); - long long duration = (itEnd - itStart) * 1e-6; // milliseconds - if ( mGenHistograms ){ - this->mHist["FitDuration"]->Fill(duration); + // End Step 5 + /***********************************************************************************************************/ + } else { + LOG_INFO << "Event configuration is skipping FWD vertex finding" << endm; } - // TODO: After tracking vertex finding... - } - void doMcTrackFinding(FwdDataSource::McTrackMap_t &mcTrackMap) { + const bool do_fwd_primary_fitting = true; + /***********************************************************************************************************/ + // Step 6: Refit the track with the primary vertex + index = 0; + if (do_fwd_primary_fitting){ + // Now try refitting every track with the primary vertex + for (auto >r : globalTracks) { + LOG_INFO << "Refitting Track " << index << ", McId=" << gtr.mIdTruth << " with Primary Vertex, seed already has: " << gtr.mSeed.size() << " hits" << endm; + LOG_INFO << "mEventVertexHit: " << mEventVertexHit.getX() << ", " << mEventVertexHit.getY() << ", " << mEventVertexHit.getZ() << endm; + // just use the global track to build the track that will use the PV also + Seed_t seedWithPV = gtr.mSeed; + seedWithPV.push_back( &mEventVertexHit ); + + // If we are using MC momentum get it from associated track + TVector3 momentumSeedStateMc; + TVector3 *pMomSeedState = >r.mMomentum; + // if (true == useMcSeedMomentum) { + // /*******************************************************/ + // // Only for Simulation + // // get the MC track momentum if we can (may be used for state seed) + // auto mctm = mDataSource->getMcTracks(); + // if (mctm.count(gtr.mIdTruth)) { + // auto mct = mctm[gtr.mIdTruth]; + // momentumSeedStateMc.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi); + // pMomSeedState = &momentumSeedStateMc; + // LOG_INFO << "Setting momentum to MC Seed state value for primary refit" << endm; + // } else {} + // /*******************************************************/ + // } // else if pMomSeedState = nullptr, a seed momentum will be computed from seed points by tracker + + GenfitTrackResult gtrPV = fitTrack(seedWithPV, pMomSeedState); + if ( gtrPV.mIsFitConvergedFully ){ + mEventStats.mGoodPrimaryFits++; + } else { + mEventStats.mFailedPrimaryFits++; + continue; + } + gtrPV.setDCA( mEventVertex ); + gtrPV.isPrimary = true; + mEventStats.mAttemptedPrimaryFits ++; + primaryTracks.push_back( gtrPV ); + index++; + } + // End Step 6 + /***********************************************************************************************************/ + } else { + LOG_INFO << "Event configuration is skipping primary track fitting" << endm; + } - mQualityPlotter->startIteration(); + float perGoodPrim = (float) mEventStats.mGoodPrimaryFits / (float) mEventStats.mAttemptedPrimaryFits; + float perFailedPrim = (float) mEventStats.mFailedPrimaryFits / (float) mEventStats.mAttemptedPrimaryFits; + LOG_DEBUG << "\tPrimary Track Fitting Results:" << + TString::Format( + "Attempts = %d, Good = %d (%f%%), Failed = %d (%f%%)", + mEventStats.mAttemptedPrimaryFits, + mEventStats.mGoodPrimaryFits, + perGoodPrim, + mEventStats.mFailedPrimaryFits, + perFailedPrim + ) << endm; + + // Add the global and primary tracks to the results + LOG_DEBUG << "Ending track fitting loop, mTrackResults.size() = " << mTrackResults.size() << endm; + mTrackResults.insert( mTrackResults.end(), globalTracks.begin(), globalTracks.end() ); + LOG_DEBUG << "Copied globals, now mTrackResults.size() = " << mTrackResults.size() << endm; + mTrackResults.insert( mTrackResults.end(), primaryTracks.begin(), primaryTracks.end() ); + + long long duration2 = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + LOG_DEBUG << "Track fitting took " << duration2 << "ms" << endm; + LOG_DEBUG << "We fit " << globalTracks.size() << " global tracks and " << primaryTracks.size() << " primary tracks, total = " << mTrackResults.size() << endm; + } // doTrackFitting + + /** + * @brief MC track finding builds track seeds from available hits using MC association + * + * @param mcTrackMap : Mc tracks + * @param useFttAsSource : Use FTT for seeds or (false) use Fst + */ + void doMcTrackFinding(FwdDataSource::McTrackMap_t &mcTrackMap, int seedSource) { + LOG_INFO << "Running MC Seed Finding, mode: " << seedSource << endm; + // If we want sequential MC track finding then do them each individually + if ( seedSource == kSeqSeed ){ + doMcTrackFinding( mcTrackMap, kFstSeed ); + doMcTrackFinding( mcTrackMap, kFttSeed ); + return; + } + + mTrackSeedsThisIteration.clear(); // we will build reco tracks from each McTrack for (auto kv : mcTrackMap) { - + auto mc_track = kv.second; - if (mc_track->mHits.size() < 4){ // require min 4 hits on track + LOG_DEBUG << "McTrack[ " << kv.first << " ]: nFtt=" << mc_track->mFttHits.size() << ", nFst=" << mc_track->mFstHits.size() << endm; + + if (seedSource == kFttSeed && mc_track->mFttHits.size() < 2){ // require min 4 FTT hits on track + continue; + } + + if (seedSource == kFstSeed && mc_track->mFstHits.size() < 2 ) { // require min 3 FST hits on track + LOG_DEBUG << "Skipping McSeedFinding bc FST hits < 2" << endm; + continue; + } + + if ( seedSource == kSimSeed && mc_track->mFstHits.size() < 2 && mc_track->mFttHits.size() < 2 ){ continue; } std::set uvid; Seed_t track; - for (auto h : mc_track->mHits) { - track.push_back(h); - uvid.insert(static_cast(h)->_vid); + if ( seedSource != kFstSeed ){ // FTT is used unless we are ONLY considering FST + for (auto h : mc_track->mFttHits) { + track.push_back(h); + uvid.insert(static_cast(h)->_vid); + } + } + if (seedSource != kFttSeed ) { // FST + for (auto h : mc_track->mFstHits) { + track.push_back(h); + uvid.insert(static_cast(h)->_vid); + } } if (uvid.size() == track.size()) { // only add tracks that have one hit per volume - mRecoTracks.push_back(track); + mTrackSeedsThisIteration.push_back(track); int idt = 0; double qual = 0; idt = MCTruthUtils::dominantContribution(track, qual); - mRecoTrackQuality.push_back(qual); - mRecoTrackIdTruth.push_back(idt); } else { - //Skipping track that doesnt have hits on all layers + //Skipping track that doesnt have hits on all layers } } - LOG_DEBUG << "McTrackFinding Found: " << mRecoTracks.size() << " tracks" << endm; - - doTrackFitting(mRecoTracks); - - if ( mGenHistograms ){ - mQualityPlotter->afterIteration(0, mRecoTracks); - } - } + LOG_DEBUG << "McTrackFinding Found: " << mTrackSeedsThisIteration.size() << " tracks" << endm; + // doTrackFitting(mTrackSeedsThisIteration); + // Now save to the main reco track list + mTrackSeeds.insert( mTrackSeeds.end(), mTrackSeedsThisIteration.begin(), mTrackSeedsThisIteration.end() ); + } //doMcTrackFinding /** sliceHitMapInPhi * @brief Slices a hitmap into a phi section - * + * * @param inputMap INPUT hitmap to process * @param outputMap OUTPUT hitmap, will be cleared and filled with only the hits from inputMap that are within phi region * @param phi_min The minimum phi to accept * @param phi_max The maximum Phi to accept - * + * * @returns The number of hits in the outputMap */ size_t sliceHitMapInPhi( FwdDataSource::HitMap_t &inputMap, FwdDataSource::HitMap_t &outputMap, float phi_min, float phi_max ){ @@ -770,19 +1068,18 @@ class ForwardTrackMaker { } // loop on hits } // loop on map return n_hits_kept; - } + } // sliceHitMapInPhi - /** doTrackingOnHitmapSubset + /** doSeedFindingOnHitmapSubset * @brief Does track finding steps on a subset of hits (phi slice) * @param iIteration: tracking iteration (for determining params) * @param hitmap: the hitmap to use, should already be subset of original * @returns a list of track seeds */ - vector doTrackingOnHitmapSubset( size_t iIteration, FwdDataSource::HitMap_t &hitmap ) { + vector doSeedFindingOnHitmapSubset( size_t iIteration, FwdDataSource::HitMap_t &hitmap ) { long long itStart = FwdTrackerUtils::nowNanoSecond(); - std::vector acceptedTracks; - std::vector rejectedTracks; + std::vector acceptedTrackSeeds; /*************************************************************/ // Step 2 // build 2-hit segments (setup parent child relationships) @@ -800,7 +1097,7 @@ class ForwardTrackMaker { criteriaPath = "TrackFinder.SegmentBuilder"; } - mTwoHitCrit.clear(); + clearCriteria( mTwoHitCrit ); mTwoHitCrit = loadCriteria(criteriaPath); builder.addCriteria(mTwoHitCrit); @@ -811,19 +1108,22 @@ class ForwardTrackMaker { connPath = "TrackFinder.Connector"; unsigned int distance = mConfig.get(connPath + ":distance", 1); - + if (mSeedSource == kFttSeed){ + distance = 2; // set distance to 2 for FTT + } + FwdConnector connector(distance); builder.addSectorConnector(&connector); - + LOG_DEBUG << "Connector added: " << endm; // Get the segments and return an automaton object for further work - + KiTrack::Automaton automaton = builder.get1SegAutomaton(); LOG_DEBUG << TString::Format( "nSegments=%lu", automaton.getSegments().size() ).Data() << endm; LOG_DEBUG << TString::Format( "nConnections=%u", automaton.getNumberOfConnections() ).Data() << endm; - if (automaton.getNumberOfConnections() > 900 ){ + if (automaton.getNumberOfConnections() > 9000 ){ LOG_ERROR << "Got too many connections, bailing out of tracking" << endm; - return acceptedTracks; + return acceptedTrackSeeds; } // at any point we can get a list of tracks out like this: @@ -831,8 +1131,7 @@ class ForwardTrackMaker { // we can apply an optional parameter to only get tracks with >=nHits in them long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) - mHist["Step2Duration"]->Fill( duration ); + mEventStats.mStep2Duration.push_back(duration); itStart = FwdTrackerUtils::nowNanoSecond(); /*************************************************************/ @@ -846,35 +1145,20 @@ class ForwardTrackMaker { if (false == mConfig.exists(criteriaPath)) criteriaPath = "TrackFinder.ThreeHitSegments"; - mThreeHitCrit.clear(); + clearCriteria( mThreeHitCrit ); mThreeHitCrit = loadCriteria(criteriaPath); automaton.addCriteria(mThreeHitCrit); - automaton.lengthenSegments(); - - bool doAutomation = mConfig.get(criteriaPath + ":doAutomation", true); - bool doCleanBadStates = mConfig.get(criteriaPath + ":cleanBadStates", true); - - if (doAutomation) { - automaton.doAutomaton(); - } else { - //Not running Automation Step - } - - if (doAutomation && doCleanBadStates) { - automaton.cleanBadStates(); - } duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) - mHist["Step3Duration"]->Fill( duration ); - if (duration > 200 || automaton.getNumberOfConnections() > 900){ + mEventStats.mStep3Duration.push_back( duration ); + if (duration > 2000 || automaton.getNumberOfConnections() > 9000){ LOG_WARN << "The Three Hit Criteria took more than 200ms to process, duration: " << duration << " ms" << endm; LOG_WARN << "bailing out (skipping subset HNN)" << endm; - std::vector acceptedTracks; + std::string subsetPath = "TrackFinder.Iteration[" + std::to_string(iIteration) + "].SubsetNN"; size_t minHitsOnTrack = mConfig.get(subsetPath + ":min-hits-on-track", FwdSystem::sNFttLayers); - acceptedTracks = automaton.getTracks(minHitsOnTrack); - return acceptedTracks; + acceptedTrackSeeds = automaton.getTracks(minHitsOnTrack); + return acceptedTrackSeeds; } itStart = FwdTrackerUtils::nowNanoSecond(); @@ -915,46 +1199,48 @@ class ForwardTrackMaker { subset.calculateBestSet(comparer, quality); - acceptedTracks = subset.getAccepted(); + acceptedTrackSeeds = subset.getAccepted(); // this call takes a long time due to possible huge combinatorics. // rejectedTracks = subset.getRejected(); - // LOG_DEBUG << "We had " << tracks.size() << " tracks. Accepted = " << acceptedTracks.size() << ", Rejected = " << rejectedTracks.size() << endm; + // LOG_DEBUG << "We had " << tracks.size() << " tracks. Accepted = " << acceptedTrackSeeds.size() << ", Rejected = " << rejectedTracks.size() << endm; } else { // the subset and hit removal size_t minHitsOnTrack = mConfig.get(subsetPath + ":min-hits-on-track", FwdSystem::sNFttLayers); - acceptedTracks = automaton.getTracks(minHitsOnTrack); + acceptedTrackSeeds = automaton.getTracks(minHitsOnTrack); }// subset off duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) - mHist["Step4Duration"]->Fill( duration ); + mEventStats.mStep4Duration.push_back( duration ); if (duration > 500){ LOG_WARN << "The took more than 500ms to process, duration: " << duration << " ms" << endm; - LOG_WARN << "We got " << acceptedTracks.size() << " tracks this round" << endm; + LOG_WARN << "We got " << acceptedTrackSeeds.size() << " tracks this round" << endm; } - LOG_DEBUG << "We got " << acceptedTracks.size() << " tracks this round" << endm; - return acceptedTracks; - } // doTrackingOnHitmapSubset - - void doTrackIteration(size_t iIteration, FwdDataSource::HitMap_t &hitmap) { + LOG_DEBUG << "We got " << acceptedTrackSeeds.size() << " tracks this round" << endm; + return acceptedTrackSeeds; + } // doSeedFindingOnHitmapSubset + + /** + * @brief Main tracking procedure + * + * @param iIteration : The track iteration + * @param hitmap : the hitmap of available hits per plane + */ + void doSeedFindingIteration(size_t iIteration, FwdDataSource::HitMap_t &hitmap) { // empty the list of reco tracks for the iteration - mRecoTracksThisItertion.clear(); + mTrackSeedsThisIteration.clear(); // check to see if we have hits! size_t nHitsThisIteration = nHitsInHitMap(hitmap); - if (nHitsThisIteration < 4) { + const int minHitsToConsider = 3; + if (nHitsThisIteration < minHitsToConsider) { // No hits left in the hitmap! Skipping this iteration + LOG_INFO << "No hits to consider in this iteration, skipping" << endm; return; } - // this starts the timer for the iteration - if ( mGenHistograms ){ - mQualityPlotter->startIteration(); - } - std::string pslPath = "TrackFinder.Iteration["+ std::to_string(iIteration) + "]:nPhiSlices"; if ( false == mConfig.exists( pslPath ) ) pslPath = "TrackFinder:nPhiSlices"; size_t phi_slice_count = mConfig.get( pslPath, 1 ); @@ -964,12 +1250,12 @@ class ForwardTrackMaker { /*************************************************************/ // Steps 2 - 4 here /*************************************************************/ - auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, hitmap ); - mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() ); + auto acceptedTracks = doSeedFindingOnHitmapSubset( iIteration, hitmap ); + mTrackSeedsThisIteration.insert( mTrackSeedsThisIteration.end(), acceptedTracks.begin(), acceptedTracks.end() ); } else { FwdDataSource::HitMap_t slicedHitMap; - + if ( phi_slice_count == 0 || phi_slice_count > 100 ){ LOG_WARN << "Invalid phi_slice_count = " << phi_slice_count << ", resetting to 1" << endm; phi_slice_count= 1; @@ -979,31 +1265,32 @@ class ForwardTrackMaker { float phi_min = phi_slice_index * phi_slice - TMath::Pi(); float phi_max = (phi_slice_index + 1) * phi_slice - TMath::Pi(); + LOG_INFO << TString::Format( "phi slice = (%f, %f)", phi_min, phi_max ) << endm; /*************************************************************/ - // Step 1A + // Step 1 // Slice the hitmap into a phi section if needed // If we do that, check again that we arent wasting time on empty sections /*************************************************************/ size_t nHitsThisSlice = 0; if ( phi_slice_count > 1 ){ nHitsThisSlice = sliceHitMapInPhi( hitmap, slicedHitMap, phi_min, phi_max ); - if ( nHitsThisSlice < 4 ) { + if ( nHitsThisSlice < minHitsToConsider ) { continue; } } else { // no need to slice // I think this incurs a copy, maybe we can find a way to avoid. slicedHitMap = hitmap; } - + /*************************************************************/ // Steps 2 - 4 here /*************************************************************/ - auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, slicedHitMap ); - mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() ); + auto acceptedTracks = doSeedFindingOnHitmapSubset( iIteration, slicedHitMap ); + mTrackSeedsThisIteration.insert( mTrackSeedsThisIteration.end(), acceptedTracks.begin(), acceptedTracks.end() ); } //loop on phi slices }// if loop on phi slices - LOG_INFO << "."; + /*************************************************************/ // Step 5 // Remove the hits from any track that was found @@ -1012,188 +1299,164 @@ class ForwardTrackMaker { if ( false == mConfig.exists( hrmPath ) ) hrmPath = "TrackFinder.HitRemover"; if ( true == mConfig.get( hrmPath + ":active", true ) ){ - removeHits( hitmap, mRecoTracksThisItertion ); + removeHits( hitmap, mTrackSeedsThisIteration ); } - - LOG_DEBUG << " FITTING " << mRecoTracksThisItertion.size() << " now" << endm; - if ( mRecoTracksThisItertion.size() < 201 ){ - doTrackFitting( mRecoTracksThisItertion ); - } else { - LOG_ERROR << "BAILING OUT of fit, too many track candidates" << endm; - } - - if ( mGenHistograms ){ - mQualityPlotter->afterIteration( iIteration, mRecoTracksThisItertion ); - } - + LOG_DEBUG << " Found " << mTrackSeedsThisIteration.size() << " seed tracks this iteration" << endm; // Add the set of all accepted tracks (this iteration) to our collection of found tracks from all iterations - mRecoTracks.insert( mRecoTracks.end(), mRecoTracksThisItertion.begin(), mRecoTracksThisItertion.end() ); + mTrackSeeds.insert( mTrackSeeds.end(), mTrackSeedsThisIteration.begin(), mTrackSeedsThisIteration.end() ); + } // doSeedFindingIteration - } // doTrackIteration - - void addSiHitsMc() { + /** + * @brief Adds compatible FST hits to tracks seeded with FTT + * + */ + void addFstHitsMc( GenfitTrackResult >r ) { FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); - - for (size_t i = 0; i < mTrackResults.size(); i++) { - GenfitTrackResult >r = mTrackResults[i]; - - if ( gtr.status.isFitConverged() == false || gtr.momentum.Perp() < 1e-3) { - LOG_DEBUG << "Skipping addSiHitsMc, fit failed" << endm; - return; - } - - if ( mGenHistograms){ - mHist["FitStatus"]->Fill("PossibleReFit", 1); - } - - Seed_t si_hits_for_this_track(3, nullptr); - - for (size_t j = 0; j < 3; j++) { - for (auto h0 : hitmap[j]) { - if (dynamic_cast(h0)->_tid == gtr.track->getMcTrackId()) { - si_hits_for_this_track[j] = h0; - break; - } - } // loop on hits in this layer of hitmap - } // loop on hitmap layers - - size_t nSiHitsFound = 0; - if ( si_hits_for_this_track[0] != nullptr ) nSiHitsFound++; - if ( si_hits_for_this_track[1] != nullptr ) nSiHitsFound++; - if ( si_hits_for_this_track[2] != nullptr ) nSiHitsFound++; - LOG_DEBUG << "Found " << nSiHitsFound << " FST Hits on this track (MC lookup)" << endm; - - if ( mGenHistograms ){ - this->mHist[ "nSiHitsFound" ]->Fill( 1, ( si_hits_for_this_track[0] != nullptr ? 1 : 0 ) ); - this->mHist[ "nSiHitsFound" ]->Fill( 2, ( si_hits_for_this_track[1] != nullptr ? 1 : 0 ) ); - this->mHist[ "nSiHitsFound" ]->Fill( 3, ( si_hits_for_this_track[2] != nullptr ? 1 : 0 ) ); - } - - if (nSiHitsFound >= 1) { - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("AttemptReFit", 1); - } - TVector3 p = mTrackFitter->refitTrackWithSiHits(gtr.track, si_hits_for_this_track); - - if ( mGenHistograms ){ - if (p.Perp() == mFitMoms[i].Perp()) { - mHist["FitStatus"]->Fill("BadReFit", 1); - LOG_DEBUG << "refitTrackWithSiHits failed refit" << endm; - } else { - mHist["FitStatus"]->Fill("GoodReFit", 1); - gtr.setFst( si_hits_for_this_track, mTrackFitter->getTrack() ); - } + if ( gtr.mStatus->isFitConverged() == false || gtr.mMomentum.Perp() < 1e-3) { + LOG_DEBUG << "Skipping addFstHitsMc, fit failed" << endm; + return; + } + mEventStats.mPossibleReFit++; + Seed_t fstHitsThisTrack; + + for (size_t j = 0; j < 3; j++) { + for (auto h0 : hitmap[j]) { + if (dynamic_cast(h0)->_tid == gtr.mIdTruth) { + fstHitsThisTrack.push_back(h0); + break; } + } // loop on hits in this layer of hitmap + } // loop on hitmap layers + + LOG_DEBUG << "Found " << gtr.mSeed.size() << " existing seed points" << endm; + LOG_DEBUG << "Adding " << fstHitsThisTrack.size() << " new FST seed points" << endm; + + if (fstHitsThisTrack.size() >= 1) { + mEventStats.mAttemptedReFits++; + gtr.mSeed.insert( gtr.mSeed.end(), fstHitsThisTrack.begin(), fstHitsThisTrack.end() ); + } // we have 3 Si hits to refit with + } // addFstHitsMc + + /** + * @brief Adds compatible FTT hits to tracks seeded with FST + * + * @param gtr : The GenfitTrackResult to add FTT hits to + * @param disk : The FTT disk number + * @return Seed_t : The combined seed points + */ + void addFttHits( GenfitTrackResult >r, size_t disk ) { + FwdDataSource::HitMap_t hitmap = mDataSource->getFttHits(); + if ( disk > 3 ) { + LOG_WARN << "Invalid FTT disk number: " << disk << ", cannot add Ftt points to track" << endm; + return; + } + if (gtr.mIsFitConverged != true) + return; + mEventStats.mPossibleReFit++; - mNumFstHits[i] = nSiHitsFound; - mFitMoms[i] = p; - } // we have 3 Si hits to refit with - - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill( TString::Format( "w%luSi", nSiHitsFound ).Data(), 1 ); - } - - } // loop on the global tracks - } // ad Si hits via MC associations - - void addSiHits() { - FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); - - // loop on global tracks - for (size_t i = 0; i < mGlobalTracks.size(); i++) { - if (mGlobalTracks[i]->getFitStatus(mGlobalTracks[i]->getCardinalRep())->isFitConverged() == false) { - // Original Track fit did not converge, skipping - return; - } - - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("PossibleReFit", 1); - } - - Seed_t hits_near_disk0; - Seed_t hits_near_disk1; - Seed_t hits_near_disk2; - try { - auto msp2 = mTrackFitter->projectToFst(2, mGlobalTracks[i]); - auto msp1 = mTrackFitter->projectToFst(1, mGlobalTracks[i]); - auto msp0 = mTrackFitter->projectToFst(0, mGlobalTracks[i]); - - // now look for Si hits near these - hits_near_disk2 = findSiHitsNearMe(hitmap[2], msp2); - hits_near_disk1 = findSiHitsNearMe(hitmap[1], msp1); - hits_near_disk0 = findSiHitsNearMe(hitmap[0], msp0); - } catch (genfit::Exception &e) { - // Failed to project to Si disk: ", e.what() - } + Seed_t hits_near_plane; + try { + auto msp = mTrackFitter->projectToFtt(disk, gtr.mTrack); + + // now look for Ftt hits near the specified state + hits_near_plane = findFttHitsNearProjectedState(hitmap[disk], msp); + LOG_DEBUG << " Found #FTT hits on plane #" << disk << TString::Format( " = [%ld]", hits_near_plane.size() ) << endm; + } catch (genfit::Exception &e) { + // Failed to project + LOG_WARN << "Unable to get Ftt projections: " << e.what() << endm; + } - vector hits_to_add; + LOG_DEBUG << "Found " << gtr.mSeed.size() << " existing seed points" << endm; - size_t nSiHitsFound = 0; // this is really # of disks on which a hit is found + if ( hits_near_plane.size() > 0 ){ + mEventStats.mAttemptedReFits++; + LOG_DEBUG << "Adding " << hits_near_plane.size() << " new FTT seed points" << endm; + gtr.mSeed.insert( gtr.mSeed.end(), hits_near_plane.begin(), hits_near_plane.end() ); + } + return; + } // addFttHits - if ( mGenHistograms ){ - this->mHist[ "nSiHitsFound" ]->Fill( 1, hits_near_disk0.size() ); - this->mHist[ "nSiHitsFound" ]->Fill( 2, hits_near_disk1.size() ); - this->mHist[ "nSiHitsFound" ]->Fill( 3, hits_near_disk2.size() ); - } + /** + * @brief Adds compatible FTT hits using MC info + * + */ + void addFttHitsMc( GenfitTrackResult >r ) { + LOG_DEBUG << "Looking for FTT hits on this track (MC lookup)" << endm; + LOG_DEBUG << "Track TruthId = " << gtr.mIdTruth << " vs. " << gtr.mTrack->getMcTrackId() << endm; + FwdDataSource::HitMap_t hitmap = mDataSource->getFttHits(); + if ( gtr.mStatus->isFitConverged() == false || gtr.mMomentum.Perp() < 1e-6) { + LOG_DEBUG << "Skipping addFttHitsMc on this track, fit failed" << endm; + return; + } - // TODO: HANDLE multiple points found? - if ( hits_near_disk0.size() == 1 ) { - hits_to_add.push_back( hits_near_disk0[0] ); - nSiHitsFound++; - } else { - hits_to_add.push_back( nullptr ); - } - if ( hits_near_disk1.size() == 1 ) { - hits_to_add.push_back( hits_near_disk1[0] ); - nSiHitsFound++; - } else { - hits_to_add.push_back( nullptr ); - } - if ( hits_near_disk2.size() == 1 ) { - hits_to_add.push_back( hits_near_disk2[0] ); - nSiHitsFound++; - } else { - hits_to_add.push_back( nullptr ); - } + mEventStats.mPossibleReFit++; + Seed_t fttHitsForThisTrack; - if (nSiHitsFound >= 1) { - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill("AttemptReFit", 1); - } - // LOG_INFO << "Fitting on GlobalTrack : " << mGlobalTracks[i] << " with " << nSiHitsFound << " si hits" << endm; - TVector3 p = mTrackFitter->refitTrackWithSiHits(mGlobalTracks[i], hits_to_add); - size_t lengthGTR = mTrackResults.size(); - if ( lengthGTR >= 1 ){ - mTrackResults[ lengthGTR - 1 ].setFst( hits_to_add, mTrackFitter->getTrack() ); - } else { - LOG_ERROR << "Fit Results not found" << endm; + for (size_t j = 0; j < 4; j++) { + for (auto h0 : hitmap[j]) { + if (dynamic_cast(h0)->_tid == gtr.mIdTruth) { + fttHitsForThisTrack.push_back( h0 ); + break; } + } // loop on hits in this layer of hitmap + } // loop on hitmap layers + + LOG_DEBUG << "Found " << fttHitsForThisTrack.size() << " FTT Hits on this track (MC lookup)" << endm; + + if (fttHitsForThisTrack.size() >= 1) { + mEventStats.mAttemptedReFits++; + gtr.mSeed.insert( gtr.mSeed.end(), fttHitsForThisTrack.begin(), fttHitsForThisTrack.end() ); + } // we have at least one Fst hit to refit with + } // add Ftt hits via MC associations + + /** + * @brief Adds compatible FST hits to a track + * + * @param gtr : The GenfitTrackResult to add FST hits to + * @param disk : The FST disk number + */ + void addFstHits( GenfitTrackResult >r, size_t disk ) { + FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits(); + if (gtr.mIsFitConverged == false) { + // Original Track fit did not converge, skipping + return; + } + if ( disk > 2 ){ + LOG_ERROR << "Invalid FST disk number: " << disk << endm; + return; + } + mEventStats.mPossibleReFit++; - if ( mGenHistograms ){ - if (p.Perp() == mFitMoms[i].Perp()) { - mHist["FitStatus"]->Fill("BadReFit", 1); - } else { - mHist["FitStatus"]->Fill("GoodReFit", 1); - } - } - - // mGlobalTracks[i] = mTrackFitter->getTrack(); - mNumFstHits[i] = nSiHitsFound; - mFitMoms[i] = p; - - } else { - // unable to refit - } - - if ( mGenHistograms ){ - mHist["FitStatus"]->Fill( TString::Format( "w%luSi", nSiHitsFound ).Data(), 1 ); - } - - } // loop on globals - } // addSiHits + Seed_t nearby_hits; + try { + // get measured state on plane at specified disk + auto msp = mTrackFitter->projectToFst(disk, gtr.mTrack); + // now look for Si hits near this state + nearby_hits = findFstHitsNearProjectedState(hitmap[disk], msp); + } catch (genfit::Exception &e) { + LOG_WARN << "Unable to get projections: " << e.what() << endm; + } + LOG_DEBUG << "Track already has " << gtr.mSeed.size() << " existing seed points" << endm; - Seed_t findSiHitsNearMe(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dphi = 0.004 * 9.5, double dr = 2.75) { + if ( nearby_hits.size() > 0 ){ + mEventStats.mAttemptedReFits++; + LOG_DEBUG << "Adding " << nearby_hits.size() << " new FST seed points from disk " << disk << endm; + gtr.mSeed.insert( gtr.mSeed.end(), nearby_hits.begin(), nearby_hits.end() ); + } + return; + } // addFstHits + + /** + * @brief Finds FST hits near projected state + * + * @param available_hits : FST hits to consider + * @param msp : measured state on plabe from existing track projection + * @param dphi : search distance in phi + * @param dr : search distance in r + * @return Seed_t : compatible FST hits + */ + Seed_t findFstHitsNearProjectedState(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dphi = 0.004 * 20.5, double dr = 2.75 * 2) { double probe_phi = TMath::ATan2(msp.getPos().Y(), msp.getPos().X()); double probe_r = sqrt(pow(msp.getPos().X(), 2) + pow(msp.getPos().Y(), 2)); @@ -1203,51 +1466,109 @@ class ForwardTrackMaker { double h_phi = TMath::ATan2(h->getY(), h->getX()); double h_r = sqrt(pow(h->getX(), 2) + pow(h->getY(), 2)); double mdphi = fabs(h_phi - probe_phi); - + if (mdphi > 2*3.1415926) + mdphi = mdphi - 2*3.1415926; + if ( mdphi < dphi && fabs( h_r - probe_r ) < dr) { // handle 2pi edge found_hits.push_back(h); } } return found_hits; - } + } // findFstHitsNearProjectedState + + /** + * @brief Finds FTT hits near projected state + * + * @param available_hits : FTT hits to consider + * @param msp : measured state on plane from existing track fit projection + * @param dx : search distance in x + * @param dy : search distance in y + * + * @return compatible FTT hits + */ + Seed_t findFttHitsNearProjectedState(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dx = 1.5, double dy = 1.5) { + + Seed_t found_hits; + TLorentzVector lv1, lv2; + lv1.SetPxPyPzE( msp.getPos().X(), msp.getPos().Y(), 0, 1 ); + + double mindx = 99; + double mindy = 99; + double mindr = 99; + double mindp = 99; + KiTrack::IHit *closest = nullptr; + + for (auto h : available_hits) { + + lv2.SetPxPyPzE( h->getX(), h->getY(), 0, 1 ); + double sr = lv1.Pt() - lv2.Pt(); + double sp = lv1.DeltaPhi( lv2 ); + double sx = h->getX() - msp.getPos().X(); + double sy = h->getY() - msp.getPos().Y(); + + if ( fabs(sr) < fabs(mindr) ) + mindr = sr; + if ( fabs(sp) < fabs(mindp) ){ + mindp = sp; + closest = h; + } + if ( fabs(sx) < fabs(mindx) ) + mindx = sx; + if ( fabs(sy) < fabs(mindy) ) + mindy = sy; + + } // loop h + + if ( fabs(mindp) < 0.04*5 && fabs(mindr) < 9 ) { + found_hits.push_back(closest); + } + + return found_hits; + } // findFttHitsNearProjectedState bool getSaveCriteriaValues() { return mSaveCriteriaValues; } std::vector getTwoHitCriteria() { return mTwoHitCrit; } std::vector getThreeHitCriteria() { return mThreeHitCrit; } TrackFitter *getTrackFitter() { return mTrackFitter; } - void setEventVertex( TVector3 v ) { mEventVertex = v; } + void setEventVertex( TVector3 v, TMatrixDSym cov ){ + mEventVertex = v; + // this is the FwdHit we will use in seeds + mEventVertexHit.setXYZDetId( v.X(), v.Y(), v.Z(), kTpcId ); + for (size_t i=0; i < 3; i++){ + for (size_t j=0; j < 3; j++){ + mEventVertexHit._covmat(i,j) = cov(i,j); + } + } + } + TVector3 getEventVertex() { return mEventVertex; } protected: unsigned long long int nEvents; bool mDoTrackFitting = true; - bool mSaveCriteriaValues = true; + bool mSaveCriteriaValues = false; + enum SeedSource { kFstSeed = 0, kFttSeed, kSimSeed, kSeqSeed }; + int mSeedSource = 1; // 0 = FST, 1 = FTT, 2 = FST+FTT simultaneous, 3 = FST+FTT sequential FwdTrackerConfig mConfig; std::string mConfigFile; size_t mTotalHitsRemoved; - + std::vector mTrackResults; - std::vector mRecoTracks; // the tracks recod from all iterations - std::vector mRecoTracksThisItertion; + std::vector mTrackSeeds; // the tracks recod from all iterations + std::vector mTrackSeedsThisIteration; + + // Metrics about the event + EventStats mEventStats; // Set to the Primary vertex for the event TVector3 mEventVertex; - - // These are vectors with info about each track / fit - // they should all have the same length - std::vector mRecoTrackQuality; - std::vector mRecoTrackIdTruth; - std::vector mFitMoms; - std::vector mNumFstHits; - std::vector mFitStatus; - std::vector mGlobalTrackReps; - std::vector mGlobalTracks; - - QualityPlotter *mQualityPlotter; + FwdHit mEventVertexHit; + genfit::GFRaveVertexFactory mGFRVertices; + std::shared_ptr mDataSource; TrackFitter *mTrackFitter = nullptr; @@ -1256,12 +1577,7 @@ class ForwardTrackMaker { std::vector mThreeHitCrit; // histograms of the raw input data - bool mGenHistograms = false; // controls these histograms and use of QualityPlotter TString mGeoCache; - std::map mHist; - - - }; #endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h b/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h index 623b0172452..675881ccd50 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/ObjExporter.h @@ -1,4 +1,6 @@ +#ifndef __OBJEXPORTER_H__ +#define __OBJEXPORTER_H__ #include "GenFit/FitStatus.h" #include "GenFit/GFRaveVertexFactory.h" #include @@ -51,20 +53,20 @@ class ObjExporter { numVertices++; } } - + //## OUTPUT FACES BETWEEN INTERMEDIATE POINTS: - + for(p=1; pquadrant() == kFttQuadrantA ){ mx = 0; my = 0; sx = 1.0; sy = 1.0; @@ -249,13 +250,13 @@ class ObjExporter { } } } // ftt_strips - + // Output the event info into a useful format for event display - void output( std::string filename, + void output( std::string filename, StEvent * event, - std::vector< Seed_t> seeds, - std::vector< genfit::Track *> tracks, - const std::vector< genfit::GFRaveVertex *> &vertices, + std::vector< Seed_t> seeds, + std::vector< genfit::Track *> tracks, + const std::vector< genfit::GFRaveVertex *> &vertices, std::vector &fttHits, std::vector &fstHits, std::vector &fcsPreHits, // EPD = preshower @@ -306,9 +307,9 @@ class ObjExporter { ofile << "o fstHits" << endl; ofile << "usemtl fst_hits\n" << endl; for ( auto p : fstHits ){ - - float fstphi = TMath::ATan2( p.Y(), p.X() ); - printf( "FST PHI: %f \n", fstphi ); + + // float fstphi = TMath::ATan2( p.Y(), p.X() ); + // printf( "FST PHI: %f \n", fstphi ); // tri( ofile, TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.1f, 0.1f, 3.0f, fstphi ); sphere( TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.3, 10, 10, ofile ); } @@ -318,12 +319,12 @@ class ObjExporter { if (verbose){ LOG_INFO << "Viz has " << fcsPreHits.size() << " EPD Hits" << endm; } - if ( fcsPreHits.size() > 0 ){ + if ( fcsPreHits.size() > 0 ){ ofile << "\n" << endl; ofile << "o epd" << endl; ofile << "usemtl fcs_hits\n" << endl; for ( auto p : fcsPreHits ){ - + sphere( TVector3( p.X() * SCALE, p.Y() * SCALE, -p.Z() * SCALE ), 0.25, 10, 10, ofile ); } } @@ -331,7 +332,7 @@ class ObjExporter { if (verbose){ LOG_INFO << "Viz has " << fcsClusters.size() << " FCS Hits" << endm; } - if ( fcsClusters.size() > 0 ){ + if ( fcsClusters.size() > 0 ){ ofile << "\n" << endl; ofile << "o fcs" << endl; ofile << "usemtl fcs_hits\n" << endl; @@ -343,7 +344,7 @@ class ObjExporter { i++; } } - + // Write the track seeds if (verbose){ LOG_INFO << "Viz has " << seeds.size() << " seeds" << endm; @@ -362,7 +363,7 @@ class ObjExporter { ofile << "l "; for ( size_t i = vStart; i < numVertices; i++){ - ofile << i+1 << " "; + ofile << i+1 << " "; } ofile << endl; } @@ -382,8 +383,8 @@ class ObjExporter { float zStep = 5.0; // cm for ( auto t : tracks ) { size_t vStart = numVertices; - - + + TVector3 lpoint; for ( float z = startPos.Z(); z < 875; z += zStep ){ TVector3 point = trackPosition( t, z ); @@ -393,18 +394,21 @@ class ObjExporter { vert( ofile, point.X() * SCALE, point.Y() * SCALE, -point.Z() * SCALE ); lpoint = point; } - + ofile << "l "; for ( size_t i = vStart; i < numVertices; i++){ - ofile << i+1 << " "; + ofile << i+1 << " "; } ofile << endl; } // for t in tracks } // if tracks.size() > 0 - ofile.close(); + ofile.close(); } size_t numVertices; }; + + +#endif diff --git a/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h b/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h index de55a2a53e1..928a3e933ef 100644 --- a/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h +++ b/StRoot/StFwdTrackMaker/include/Tracker/TrackFitter.h @@ -8,20 +8,6 @@ #include "GenFit/KalmanFitStatus.h" #include "GenFit/GblFitter.h" -#include "GenFit/KalmanFitter.h" -#include "GenFit/KalmanFitterInfo.h" -#include "GenFit/KalmanFitterRefTrack.h" -#include "GenFit/MaterialEffects.h" -#include "GenFit/PlanarMeasurement.h" -#include "GenFit/RKTrackRep.h" -#include "GenFit/SpacepointMeasurement.h" -#include "GenFit/StateOnPlane.h" -#include "GenFit/TGeoMaterialInterface.h" -#include "GenFit/Track.h" -#include "GenFit/TrackPoint.h" - -#include "Criteria/SimpleCircle.h" - #include "TDatabasePDG.h" #include "TGeoManager.h" #include "TMath.h" @@ -40,29 +26,35 @@ #include "StFwdTrackMaker/include/Tracker/FwdGeomUtils.h" #include "StarGenerator/UTIL/StarRandom.h" +#include "FitterUtils.h" -/* Cass for fitting tracks(space points) with GenFit +/* Class for interfacing with GenFit for fitting tracks * */ class TrackFitter { // Accessors and options public: - genfit::FitStatus getStatus() { return mFitStatus; } - genfit::AbsTrackRep *getTrackRep() { return mTrackRep; } - genfit::Track *getTrack() { return mFitTrack; } - void setGenerateHistograms( bool gen) { mGenHistograms = gen;} - + std::shared_ptr getTrack() { return mFitTrack; } public: - // ctor - // provide the main configuration object - TrackFitter(FwdTrackerConfig _mConfig, TString geoCache) : mConfig(_mConfig), mGeoCache(geoCache) { - mTrackRep = 0; - mFitTrack = 0; - } - + /** + * @brief Construct a new Track Fitter object + * + * @param _mConfig : Config object + * @param geoCache : Geometry cache filename + */ + TrackFitter(FwdTrackerConfig _mConfig, TString geoCache) : mConfig(_mConfig), mGeoCache(geoCache), mFitTrack(nullptr) {} + + /** + * @brief Setup the tracker object + * Load geometry + * Setup Material Effects + * Setup the magnetic field + * Setup the fitter + * Setup the fit planes + */ void setup() { // the geometry manager that GenFit will use @@ -77,56 +69,62 @@ class TrackFitter { // Set Material Stepper debug level genfit::MaterialEffects::getInstance()->setDebugLvl( mConfig.get("TrackFitter.MaterialEffects:DebugLvl", 0) ); - + genfit::MaterialEffects::getInstance()->setEnergyLossBetheBloch( mConfig.get("TrackFitter.MaterialEffects.EnergyLossBetheBloch", true) ); genfit::MaterialEffects::getInstance()->setNoiseBetheBloch( mConfig.get("TrackFitter.MaterialEffects.NoiseBetheBloch", true) ); genfit::MaterialEffects::getInstance()->setNoiseCoulomb( mConfig.get("TrackFitter.MaterialEffects.NoiseCoulomb", true) ); genfit::MaterialEffects::getInstance()->setEnergyLossBrems( mConfig.get("TrackFitter.MaterialEffects.EnergyLossBrems", true) ); genfit::MaterialEffects::getInstance()->setNoiseBrems( mConfig.get("TrackFitter.MaterialEffects.NoiseBrems", true) ); genfit::MaterialEffects::getInstance()->ignoreBoundariesBetweenEqualMaterials( mConfig.get("TrackFitter.MaterialEffects.ignoreBoundariesBetweenEqualMaterials", true) ); - + // do this last to override genfit::MaterialEffects::getInstance()->setNoEffects( !mConfig.get("TrackFitter:MaterialEffects", false)); // negated, true means defaul is all effects on (noEffects off) if (!mConfig.get("TrackFitter:MaterialEffects", false)){ LOG_INFO << "Turning OFF GenFit Material Effects in stepper" << endm; } - + // Determine which Magnetic field to use // Either constant field or real field from StarFieldAdaptor if (mConfig.get("TrackFitter:constB", false)) { - mBField = std::unique_ptr(new genfit::ConstField(0., 0., 5.)); // 0.5 T Bz - LOG_INFO << "StFwdTrackMaker: Tracking with constant magnetic field" << endl; + mBField = std::unique_ptr(new genfit::ConstField(0., 0., 5.0)); // 0.5 T Bz + LOG_INFO << "StFwdTrackMaker: Tracking with constant magnetic field" << endm; } else if (mConfig.get("TrackFitter:zeroB", false)) { mBField = std::unique_ptr(new genfit::ConstField(0., 0., 0.)); // ZERO FIELD - LOG_INFO << "StFwdTrackMaker: Tracking with ZERO magnetic field" << endl; + LOG_INFO << "StFwdTrackMaker: Tracking with ZERO magnetic field" << endm; } else { mBField = std::unique_ptr(new StarFieldAdaptor()); - LOG_INFO << "StFwdTrackMaker: Tracking with StarFieldAdapter" << endl; + LOG_INFO << "StFwdTrackMaker: Tracking with StarFieldAdapter" << endm; } // we must have one of the two available fields at this point // note, the pointer is still bound to the lifetime of the TackFitter - genfit::FieldManager::getInstance()->init(mBField.get()); + genfit::FieldManager::getInstance()->init(mBField.get()); // initialize the main mFitter using a KalmanFitter with reference tracks mFitter = std::unique_ptr(new genfit::KalmanFitterRefTrack()); - // Here we load several options from the config, + // Here we load several options from the config, // to customize the mFitter behavior mFitter->setMaxFailedHits(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxFailedHits", -1)); // default -1, no limit mFitter->setDebugLvl(mConfig.get("TrackFitter.KalmanFitterRefTrack:DebugLvl", 0)); // default 0, no output - mFitter->setMaxIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxIterations", 4)); // default 4 iterations + mFitter->setMaxIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MaxIterations", 40)); // default 4 iterations mFitter->setMinIterations(mConfig.get("TrackFitter.KalmanFitterRefTrack:MinIterations", 0)); // default 0 iterations + // Set the fit convergence paramters + mFitter->setRelChi2Change( mConfig.get("TrackFitter.KalmanFitterRefTrack:RelChi2Change", 1e-3) ); + // mFitter->setAbsChi2Change( mConfig.get("TrackFitter.KalmanFitterRefTrack:AbsChi2Change", 1e-3) ); + mFitter->setDeltaPval( mConfig.get("TrackFitter.KalmanFitterRefTrack:DeltaPval", 1e-3) ); + mFitter->setBlowUpFactor( mConfig.get("TrackFitter.KalmanFitterRefTrack:BlowUpFactor", 1e3) ); + // FwdGeomUtils looks into the loaded geometry and gets detector z locations if present FwdGeomUtils fwdGeoUtils( gMan ); - // these default values are the default if the detector is - // a) not found in the geometry + // these default values are the default if the detector is + // a) not found in the geometry // b) not provided in config // NOTE: these defaults are needed since the geometry file might not include FST (bug being worked on separately) mFSTZLocations = fwdGeoUtils.fstZ( - mConfig.getVector("TrackFitter.Geometry:fst", + mConfig.getVector("TrackFitter.Geometry:fst", {140.286011, 154.286011, 168.286011 } // 144.633,158.204,171.271 ) @@ -184,7 +182,7 @@ class TrackFitter { LOG_DEBUG << sstr.str() << endm; // Now load FTT - // mConfig.getVector<>(...) requires a default, hence the + // mConfig.getVector<>(...) requires a default, hence the mFTTZLocations = fwdGeoUtils.fttZ( mConfig.getVector("TrackFitter.Geometry:ftt", {281.082,304.062,325.058,348.068}) ); @@ -212,242 +210,19 @@ class TrackFitter { delim = ", "; } LOG_DEBUG << sstr.str() << endm; - - // get default vertex values used in simulation from the config - mVertexSigmaXY = mConfig.get("TrackFitter.Vertex:sigmaXY", 1.0); - mVertexSigmaZ = mConfig.get("TrackFitter.Vertex:sigmaZ", 30.0); - mVertexPos = mConfig.getVector("TrackFitter.Vertex:pos", {0.0,0.0,0.0}); - mIncludeVertexInFit = mConfig.get("TrackFitter.Vertex:includeInFit", false); - - if ( mGenHistograms ) - makeHistograms(); - } - - void makeHistograms() { - std::string n = ""; - mHist["ECalProjPosXY"] = new TH2F("ECalProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); - mHist["ECalProjSigmaXY"] = new TH2F("ECalProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 50, 0, 0.5, 50, 0, 0.5); - mHist["ECalProjSigmaR"] = new TH1F("ECalProjSigmaR", ";#sigma_{XY} (cm) at ECAL", 50, 0, 0.5); - - mHist["SiProjPosXY"] = new TH2F("SiProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); - mHist["SiProjSigmaXY"] = new TH2F("SiProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 150, 0, 15, 150, 0, 15); - - mHist["VertexProjPosXY"] = new TH2F("VertexProjPosXY", ";X;Y", 100, -5, 5, 100, -5, 5); - mHist["VertexProjSigmaXY"] = new TH2F("VertexProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 150, 0, 20, 150, 0, 20); - - mHist["VertexProjPosZ"] = new TH1F("VertexProjPosZ", ";Z;", 100, -50, 50); - mHist["VertexProjSigmaZ"] = new TH1F("VertexProjSigmaZ", ";#sigma_{Z};", 100, 0, 10); - - mHist["SiWrongProjPosXY"] = new TH2F("SiWrongProjPosXY", ";X;Y", 1000, -500, 500, 1000, -500, 500); - mHist["SiWrongProjSigmaXY"] = new TH2F("SiWrongProjSigmaXY", ";#sigma_{X};#sigma_{Y}", 50, 0, 0.5, 50, 0, 0.5); - - mHist["SiDeltaProjPosXY"] = new TH2F("SiDeltaProjPosXY", ";X;Y", 1000, 0, 20, 1000, 0, 20); - - mHist["FstDiffZVsR"] = new TH2F( "FstDiffZVsR", ";R;dz", 400, 0, 40, 500, -5, 5 ); - mHist["FstDiffZVsPhiSliceInner"] = new TH2F( "FstDiffZVsPhiSliceInner", ";slice;dz", 15, 0, 15, 500, -5, 5 ); - mHist["FstDiffZVsPhiSliceOuter"] = new TH2F( "FstDiffZVsPhiSliceOuter", ";slice;dz", 15, 0, 15, 500, -5, 5 ); - - mHist["FstDiffZVsPhiOuter"] = new TH2F( "FstDiffZVsPhiOuter", ";slice;dz", 628, 0, TMath::Pi()*2, 500, -5, 5 ); - - mHist["CorrFstDiffZVsPhiSliceInner"] = new TH2F( "CorrFstDiffZVsPhiSliceInner", ";slice;dz", 15, 0, 15, 500, -5, 5 ); - mHist["CorrFstDiffZVsPhiSliceOuter"] = new TH2F( "CorrFstDiffZVsPhiSliceOuter", ";slice;dz", 15, 0, 15, 500, -5, 5 ); - - - n = "seed_curv"; - mHist[n] = new TH1F(n.c_str(), ";curv", 1000, 0, 10000); - n = "seed_pT"; - mHist[n] = new TH1F(n.c_str(), ";pT (GeV/c)", 500, 0, 10); - n = "seed_eta"; - mHist[n] = new TH1F(n.c_str(), ";eta", 500, 0, 5); - - n = "delta_fit_seed_pT"; - mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) pT (GeV/c)", 500, -5, 5); - n = "delta_fit_seed_eta"; - mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) eta", 500, 0, 5); - n = "delta_fit_seed_phi"; - mHist[n] = new TH1F(n.c_str(), ";#Delta( fit, seed ) phi", 500, -5, 5); - - n = "FitStatus"; - mHist[n] = new TH1F(n.c_str(), ";", 5, 0, 5); - FwdTrackerUtils::labelAxis(mHist[n]->GetXaxis(), {"Total", "Pass", "Fail", "GoodCardinal", "Exception"}); - - n = "FitDuration"; - mHist[n] = new TH1F(n.c_str(), "; Duraton (ms)", 5000, 0, 50000); - - n = "FailedFitDuration"; - mHist[n] = new TH1F(n.c_str(), "; Duraton (ms)", 500, 0, 50000); - } - - // writes mHistograms stored in map only if mGenHistograms is true - void writeHistograms() { - if ( !mGenHistograms ) - return; - for (auto nh : mHist) { - nh.second->SetDirectory(gDirectory); - nh.second->Write(); - } } - /* Convert the 3x3 covmat to 2x2 by dropping z - * - */ - TMatrixDSym CovMatPlane(KiTrack::IHit *h){ - TMatrixDSym cm(2); - cm(0, 0) = static_cast(h)->_covmat(0, 0); - cm(1, 1) = static_cast(h)->_covmat(1, 1); - cm(0, 1) = static_cast(h)->_covmat(0, 1); - return cm; - } - - - /* FitSimpleCircle - * Used to determine a seed transverse momentum based on space points - * Takes a list of space points KiTrack::IHit * - * Takes three indecise used to lookup three of the possible hits within the list - */ - float fitSimpleCircle(Seed_t trackCand, size_t i0, size_t i1, size_t i2) { - float curv = 0; - - // ensure that no index is outside of range for FST or FTT volumes - if (i0 > 12 || i1 > 12 || i2 > 12) - return 0; - - try { - KiTrack::SimpleCircle sc(trackCand[i0]->getX(), trackCand[i0]->getY(), trackCand[i1]->getX(), trackCand[i1]->getY(), trackCand[i2]->getX(), trackCand[i2]->getY()); - curv = sc.getRadius(); - } catch (KiTrack::InvalidParameter &e) { - // if we got here we failed to get a valid seed. We will still try to move forward but the fit will probably fail - } - - // make sure the curv is valid - if (isinf(curv)) - curv = 999999.9; - - return curv; - } - - /* seedState - * Determines the seed position and momentum for a list of space points + /** + * @brief Get the Fst Plane object for a given hit + * + * @param h : hit + * @return genfit::SharedPlanePtr */ - float seedState(Seed_t trackCand, TVector3 &seedPos, TVector3 &seedMom) { - // we require at least 4 hits, so this should be gauranteed - if(trackCand.size() < 3){ - // failure - return 0.0; - } - - - // we want to use the LAST 3 hits, since silicon doesnt have R information - TVector3 p0, p1, p2; - // use the closest hit to the interaction point for the seed pos - FwdHit *hit_closest_to_IP = static_cast(trackCand[0]); - - // maps from to - std::map vol_map; - - // init the map - for (size_t i = 0; i < 13; i++) - vol_map[i] = -1; - - for (size_t i = 0; i < trackCand.size(); i++) { - auto fwdHit = static_cast(trackCand[i]); - vol_map[abs(fwdHit->_vid)] = i; - // find the hit closest to IP for the initial position seed - if (hit_closest_to_IP->getZ() > fwdHit->getZ()) - hit_closest_to_IP = fwdHit; - } - - // now get an estimate of the pT from several overlapping simple circle fits - // enumerate the available partitions - // 12 11 10 - // 12 11 9 - // 12 10 9 - // 11 10 9 - vector curvs; - curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[11], vol_map[10])); - curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[11], vol_map[9])); - curvs.push_back(fitSimpleCircle(trackCand, vol_map[12], vol_map[10], vol_map[9])); - curvs.push_back(fitSimpleCircle(trackCand, vol_map[11], vol_map[10], vol_map[9])); - - // average them and exclude failed fits - float mcurv = 0; - float nmeas = 0; - - for (size_t i = 0; i < curvs.size(); i++) { - if (mGenHistograms) - this->mHist["seed_curv"]->Fill(curvs[i]); - if (curvs[i] > 10) { - mcurv += curvs[i]; - nmeas += 1.0; - } - } - - if (nmeas >= 1) - mcurv = mcurv / nmeas; - else - mcurv = 10; - - // Now lets get eta information - // simpler, use farthest points from IP - if (vol_map[9] < 13) - p0.SetXYZ(trackCand[vol_map[9]]->getX(), trackCand[vol_map[9]]->getY(), trackCand[vol_map[9]]->getZ()); - - if (vol_map[10] < 13) - p1.SetXYZ(trackCand[vol_map[10]]->getX(), trackCand[vol_map[10]]->getY(), trackCand[vol_map[10]]->getZ()); - - const double K = 0.00029979; //K depends on the units used for Bfield - double pt = mcurv * K * 5; // pT from average measured curv - double dx = (p1.X() - p0.X()); - double dy = (p1.Y() - p0.Y()); - double dz = (p1.Z() - p0.Z()); - double phi = TMath::ATan2(dy, dx); - double Rxy = sqrt(dx * dx + dy * dy); - double theta = TMath::ATan2(Rxy, dz); - // double eta = -log( tantheta / 2.0 ); - // these starting conditions can probably be improvd, good study for student - - seedMom.SetPtThetaPhi(pt, theta, phi); - seedPos.SetXYZ(hit_closest_to_IP->getX(), hit_closest_to_IP->getY(), hit_closest_to_IP->getZ()); - - if (mGenHistograms) { - this->mHist["seed_pT"]->Fill(seedMom.Pt()); - this->mHist["seed_eta"]->Fill(seedMom.Eta()); - } - - return mcurv; - } - - - genfit::MeasuredStateOnPlane projectToFst(size_t si_plane, genfit::Track *fitTrack) { - if (si_plane > 2) { - genfit::MeasuredStateOnPlane nil; - return nil; - } - - auto detSi = mFSTPlanes[si_plane]; - genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); - auto TCM = fitTrack->getCardinalRep()->get6DCov(tst); - - // this returns the track length if needed - fitTrack->getCardinalRep()->extrapolateToPlane(tst, detSi); - - TCM = fitTrack->getCardinalRep()->get6DCov(tst); - - // can get the projected positions if needed - float x = tst.getPos().X(); - float y = tst.getPos().Y(); - float z = tst.getPos().Z(); - // and the uncertainties - LOG_DEBUG << "Track Uncertainty at FST (plane=" << si_plane << ") @ x= " << x << ", y= " << y << ", z= " << z << " : " << sqrt(TCM(0, 0)) << ", " << sqrt(TCM(1, 1)) << endm; - - return tst; - } - genfit::SharedPlanePtr getFstPlane( FwdHit * h ){ size_t planeId = h->getSector(); - TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); + const TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); double phi = hitXYZ.Phi(); if ( phi < 0 ) phi = TMath::Pi() * 2 + phi; @@ -467,477 +242,264 @@ class TrackFitter { } return planeCorr; + } // GetFST PLANE - } - - /* RefitTracksWithSiHits - * Takes a previously fit track re-fits it with the newly added silicon hits - * + /** + * @brief Convert the 3x3 covmat to 2x2 by dropping z + * + * @param h : hit with cov matrix + * @return TMatrixDSym : cov matrix 2x2 */ - TVector3 refitTrackWithSiHits(genfit::Track *originalTrack, Seed_t si_hits) { - // mem leak, global track is overwritten without delete. - TVector3 pOrig = originalTrack->getCardinalRep()->getMom(originalTrack->getFittedState(1, originalTrack->getCardinalRep())); - - // auto cardinalStatus = originalTrack->getFitStatus(originalTrack->getCardinalRep()); - - if (originalTrack->getFitStatus(originalTrack->getCardinalRep())->isFitConverged() == false) { - // in this case the original track did not converge so we should not refit. - // probably never get here due to previous checks - return pOrig; - } - - // Setup the Track Reps - auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); - auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); - - // get the space points on the original track - auto trackPoints = originalTrack->getPointsWithMeasurement(); - - if ((trackPoints.size() < (mFTTZLocations.size() +1) && mIncludeVertexInFit) || trackPoints.size() < mFTTZLocations.size() ) { - // we didnt get enough points for a refit - return pOrig; - } - - TVectorD rawCoords = trackPoints[0]->getRawMeasurement()->getRawHitCoords(); - double z = mFSTZLocations[0]; //first FTT plane, used if we dont have PV in fit - if (mIncludeVertexInFit) - z = rawCoords(2); - - TVector3 seedPos(rawCoords(0), rawCoords(1), z); - TVector3 seedMom = pOrig; - - // Create the ref track using the seed state - auto mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); - mFitTrack->addTrackRep(trackRepNeg); - - genfit::Track &fitTrack = *mFitTrack; - - size_t firstFTTIndex = 0; - if (mIncludeVertexInFit) { - // clone the PRIMARY VERTEX into this track - fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[0]->getRawMeasurement(), &fitTrack)); - firstFTTIndex = 1; // start on hit index 1 below - } - - // initialize the hit coords on plane - TVectorD hitCoords(2); - hitCoords[0] = 0; - hitCoords[1] = 0; - - size_t planeId(0); - int hitId(5); - - // add the hits to the track - for (auto h : si_hits) { - if ( nullptr == h ) continue; // if no Si hit in this plane, skip - - hitCoords[0] = h->getX(); - hitCoords[1] = h->getY(); - genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), h->getSector(), ++hitId, nullptr); - - planeId = h->getSector(); - - if (mFSTPlanes.size() <= planeId) { - LOG_WARN << "invalid VolumId -> out of bounds DetPlane, vid = " << planeId << endm; - return pOrig; - } - - // auto plane = mFSTPlanes[planeId]; - auto plane = getFstPlane( static_cast(h) ); - - measurement->setPlane(plane, planeId); - fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); - - - TVector3 hitXYZ( h->getX(), h->getY(), h->getZ() ); - float phi = hitXYZ.Phi(); - if ( phi < 0 ) phi = TMath::Pi() * 2 + phi; - double phi_slice = phi / (TMath::Pi() / 6.0); // 2pi/12 - int phi_index = ((int)phi_slice); - double dz = (h->getZ() - plane->getO().Z()); - - double r =sqrt( pow(hitXYZ.x(), 2) + pow(hitXYZ.y(), 2) ); - - size_t idx = phi_index % 2; - auto planeCorr = mFSTPlanesInner[planeId + idx]; - if ( r > 16 ){ - planeCorr = mFSTPlanesOuter[planeId + idx]; - } - double cdz = (h->getZ() - planeCorr->getO().Z()); - - if (mGenHistograms){ - - ((TH2*)mHist[ "FstDiffZVsR" ])->Fill( r, dz ); - - if ( r < 16 ) {// inner - mHist["FstDiffZVsPhiSliceInner"]->Fill( phi_slice, dz ); - mHist["CorrFstDiffZVsPhiSliceInner"]->Fill( phi_slice, cdz ); - } else { - mHist["FstDiffZVsPhiSliceOuter"]->Fill( phi_slice, dz ); - mHist["CorrFstDiffZVsPhiSliceOuter"]->Fill( phi_slice, cdz ); - mHist["FstDiffZVsPhiOuter"]->Fill( phi, dz ); - } - } - // mHist[ "FstDiffZVsPhiSliceInner" ]->Fill( sqrt( pow(hitXYZ.x(), 2), pow(hitXYZ.y(), 2) ), dz ); - - } - // start at 0 if PV not included, 1 otherwise - for (size_t i = firstFTTIndex; i < trackPoints.size(); i++) { - // clone the track points into this track - fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[i]->getRawMeasurement(), &fitTrack)); - } - - try { - //Track RE-Fit with GENFIT2 - // check consistency of all points - fitTrack.checkConsistency(); - - // do the actual track fit - mFitter->processTrack(&fitTrack); - - fitTrack.checkConsistency(); - - // this chooses the lowest chi2 fit result as cardinal - fitTrack.determineCardinalRep(); - - } catch (genfit::Exception &e) { - // will be caught below by converge check - LOG_WARN << "Track fit exception : " << e.what() << endm; - } - - if (fitTrack.getFitStatus(fitTrack.getCardinalRep())->isFitConverged() == false) { - // Did not converge - return pOrig; - } else { // we did converge, return new momentum - - try { - // causes seg fault - auto cardinalRep = fitTrack.getCardinalRep(); - auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); - mFitStatus = *cardinalStatus; // save the status of last fit - } catch (genfit::Exception &e) { - } - - TVector3 p = fitTrack.getCardinalRep()->getMom(fitTrack.getFittedState(1, fitTrack.getCardinalRep())); - return p; - } - return pOrig; - } // refit with Si hits - - TVector3 refitTrackWithGBL( genfit::Track *originalTrack ) { - // mem leak, global track is overwritten without delete. - TVector3 pOrig = originalTrack->getCardinalRep()->getMom(originalTrack->getFittedState(1, originalTrack->getCardinalRep())); - - // auto cardinalStatus = originalTrack->getFitStatus(originalTrack->getCardinalRep()); - - if (originalTrack->getFitStatus(originalTrack->getCardinalRep())->isFitConverged() == false) { - // in this case the original track did not converge so we should not refit. - // probably never get here due to previous checks - return pOrig; - } - - // Setup the Track Reps - auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); - auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); - - // get the space points on the original track - auto trackPoints = originalTrack->getPointsWithMeasurement(); - - - TVectorD rawCoords = trackPoints[0]->getRawMeasurement()->getRawHitCoords(); - TVector3 seedPos(rawCoords(0), rawCoords(1), rawCoords(2)); - TVector3 seedMom = pOrig; - - // Create the ref track using the seed state - auto pFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); - pFitTrack->addTrackRep(trackRepNeg); - - genfit::Track &fitTrack = *pFitTrack; - - for (size_t i = 0; i < trackPoints.size(); i++) { - // clone the track points into this track - fitTrack.insertPoint(new genfit::TrackPoint(trackPoints[i]->getRawMeasurement(), &fitTrack)); - } - - auto gblFitter = std::unique_ptr(new genfit::GblFitter()); - try { - // check consistency of all points - fitTrack.checkConsistency(); - - // do the actual track fit - mFitter->processTrack(&fitTrack); - - fitTrack.checkConsistency(); - - // this chooses the lowest chi2 fit result as cardinal - fitTrack.determineCardinalRep(); - - } catch (genfit::Exception &e) { - // will be caught below by converge check - LOG_WARN << "Track fit exception : " << e.what() << endm; - } - - if (fitTrack.getFitStatus(fitTrack.getCardinalRep())->isFitConverged() == false) { - LOG_WARN << "GBL fit did not converge" << endm; - delete pFitTrack; - return pOrig; - } else { // we did converge, return new momentum - - try { - // causes seg fault - auto cardinalRep = fitTrack.getCardinalRep(); - auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); - mFitStatus = *cardinalStatus; // save the status of last fit - } catch (genfit::Exception &e) { - LOG_WARN << "Failed to get cardinal status from converged fit" << endm; - } - auto mom = fitTrack.getCardinalRep()->getMom(fitTrack.getFittedState(1, fitTrack.getCardinalRep())); - delete pFitTrack; - return mom; - } - delete pFitTrack; - return pOrig; - } //refitwith GBL - + TMatrixDSym CovMatPlane(KiTrack::IHit *h){ + TMatrixDSym cm(2); + cm(0, 0) = static_cast(h)->_covmat(0, 0); + cm(1, 1) = static_cast(h)->_covmat(1, 1); + cm(0, 1) = static_cast(h)->_covmat(0, 1); + return cm; + } - /* Generic method for fitting space points with GenFit + /** + * @brief Get projection to given FST plane * - * + * @param fstPlane : plane index + * @param fitTrack : track to project + * @return genfit::MeasuredStateOnPlane */ - TVector3 fitSpacePoints( vector spoints, TVector3 &seedPos, TVector3 &seedMom ){ - - // setup track reps - auto trackRepPos = new genfit::RKTrackRep(mPdgPositron); - auto trackRepNeg = new genfit::RKTrackRep(mPdgElectron); - - // setup track for fit with positive and negative reps - auto mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); - mFitTrack->addTrackRep(trackRepNeg); - - genfit::Track &fitTrack = *mFitTrack; - - // try adding the points to track and fitting - try { - for ( size_t i = 0; i < spoints.size(); i++ ){ - fitTrack.insertPoint(new genfit::TrackPoint(spoints[i], &fitTrack)); - } - // do the fit against the two possible fits - mFitter->processTrackWithRep(&fitTrack, trackRepPos); - mFitter->processTrackWithRep(&fitTrack, trackRepNeg); - - } catch (genfit::Exception &e) { - LOG_ERROR << "GenFit failed to fit track with: " << e.what() << endm; + genfit::MeasuredStateOnPlane projectToFst(size_t fstPlane, std::shared_ptr fitTrack) { + if (fstPlane > 2) { + genfit::MeasuredStateOnPlane nil; + return nil; } - try { - fitTrack.checkConsistency(); - - fitTrack.determineCardinalRep(); - auto cardinalRep = fitTrack.getCardinalRep(); + auto detFst = mFSTPlanes[fstPlane]; + // TODO: Why use 1 here? + genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); + // NOTE: this returns the track length if needed + fitTrack->getCardinalRep()->extrapolateToPlane(tst, detFst); - TVector3 p = cardinalRep->getMom(fitTrack.getFittedState(1, cardinalRep)); - // sucess, return momentum - return p; - } catch (genfit::Exception &e) { - LOG_ERROR << "GenFit failed to fit track with: " << e.what() << endm; - } - return TVector3(0, 0, 0); + return tst; } - /* Fit a track + /** + * @brief Get projection to given FTT plane * - * + * @param fttPlane : plane index + * @param fitTrack : track to project + * @return genfit::MeasuredStateOnPlane */ - TVector3 fitTrack(Seed_t trackCand, double *Vertex = 0, TVector3 *McSeedMom = 0) { - long long itStart = FwdTrackerUtils::nowNanoSecond(); - if (mGenHistograms) this->mHist["FitStatus"]->Fill("Total", 1); - - // The PV information, if we want to use it - TVectorD pv(3); - - StarRandom rand = StarRandom::Instance(); - if (0 == Vertex) { // randomized from simulation - pv[0] = mVertexPos[0] + rand.gauss(mVertexSigmaXY); - pv[1] = mVertexPos[1] + rand.gauss(mVertexSigmaXY); - pv[2] = mVertexPos[2] + rand.gauss(mVertexSigmaZ); - } else { - pv[0] = Vertex[0]; - pv[1] = Vertex[1]; - pv[2] = Vertex[2]; - } - - // get the seed info from our hits - TVector3 seedMom, seedPos; - // returns track curvature if needed - seedState(trackCand, seedPos, seedMom); - - if (McSeedMom != nullptr) { - seedMom = *McSeedMom; - } - - // If we use the PV, use that as the start pos for the track - if (mIncludeVertexInFit) { - LOG_DEBUG << "Primary Vertex in fit (seed pos) @ " << TString::Format( "(%f, %f, %f)", pv[0], pv[1], pv[2] ).Data() << endm; - seedPos.SetXYZ(pv[0], pv[1], pv[2]); + genfit::MeasuredStateOnPlane projectToFtt(size_t iFttPlane, std::shared_ptr fitTrack) { + if (iFttPlane > 3) { + genfit::MeasuredStateOnPlane nil; + return nil; } + auto fttPlane = mFTTPlanes[iFttPlane]; + // TODO: why use 1 here? + genfit::MeasuredStateOnPlane tst = fitTrack->getFittedState(1); + // NOTE: this returns the track length if needed + fitTrack->getCardinalRep()->extrapolateToPlane(tst, fttPlane); + return tst; + } - if (mFitTrack){ - delete mFitTrack; + /** + * @brief setup the track from the given seed and optional primary vertex + * @param trackSeed : seed points + * @param seedMom : seed momentum + * @param seedPos : seed position + * @param Vertex : primary vertex + */ + void setupTrack(Seed_t trackSeed ) { + + // setup the track fit seed parameters + GenericFitSeeder gfs; + int seedQ = 1; + TVector3 seedPos(0, 0, 0); + TVector3 seedMom(0, 0, 10); // this default seed actually works better than a half-bad guess + gfs.makeSeed( trackSeed, seedPos, seedMom, seedQ ); + LOG_DEBUG << "Setting track fit seed position = " << TString::Format( "(%f, %f, %f)", seedPos.X(), seedPos.Y(), seedPos.Z() ) << endm; + LOG_DEBUG << "Setting track fit seed momentum = " << TString::Format( "(%f, %f, %f)", seedMom.X(), seedMom.Y(), seedMom.Z() ) << endm; + if ( seedMom.Perp() > 0.001 ){ + // because ROOT has an assert in there :/ + LOG_DEBUG << "Setting track fit seed momentum = (Pt,eta,phi)=" << TString::Format( "(%f, %f, %f)", seedMom.Pt(), seedMom.Eta(), seedMom.Phi() ) << endm; } + + LOG_DEBUG << "Setting track fit seed charge = " << seedQ << endm; // create the track representations - auto trackRepPos = new genfit::RKTrackRep(mPdgMuon); - auto trackRepNeg = new genfit::RKTrackRep(mPdgAntiMuon); + // Note that multiple track reps differing only by charge results in a silent failure of GenFit + auto theTrackRep = new genfit::RKTrackRep(mPdgMuon * -1 * seedQ); // bc pos PDG codes are for neg particles // Create the track - mFitTrack = new genfit::Track(trackRepPos, seedPos, seedMom); - mFitTrack->addTrackRep(trackRepNeg); - - - LOG_DEBUG - << "seedPos : (" << seedPos.X() << ", " << seedPos.Y() << ", " << seedPos.Z() << " )" - << ", seedMom : (" << seedMom.X() << ", " << seedMom.Y() << ", " << seedMom.Z() << " )" - << ", seedMom : (" << seedMom.Pt() << ", " << seedMom.Eta() << ", " << seedMom.Phi() << " )" - << endm; + mFitTrack = std::make_shared(theTrackRep, seedPos, seedMom); + // now add the points to the track - genfit::Track &fitTrack = *mFitTrack; - - size_t planeId(0); // detector plane ID int hitId(0); // hit ID + size_t planeId(0); // detector plane ID // initialize the hit coords on plane TVectorD hitCoords(2); hitCoords[0] = 0; hitCoords[1] = 0; - /****************************************************************************************************************** - * Include the Primary vertex if desired - ******************************************************************************************************************/ - if (mIncludeVertexInFit) { - - TMatrixDSym hitCov3(3); - hitCov3(0, 0) = mVertexSigmaXY * mVertexSigmaXY; - hitCov3(1, 1) = mVertexSigmaXY * mVertexSigmaXY; - hitCov3(2, 2) = mVertexSigmaZ * mVertexSigmaZ; - - genfit::SpacepointMeasurement *measurement = new genfit::SpacepointMeasurement(pv, hitCov3, 0, ++hitId, nullptr); - fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); - } - /****************************************************************************************************************** * loop over the hits, add them to the track ******************************************************************************************************************/ - for (auto h : trackCand) { - + // use these to enforce our sorting parameters + size_t idxFst = 0; // index of the FST hit + size_t idxFtt = 0; // index of the FTT hit + for (auto h : trackSeed) { + auto fh = dynamic_cast(h); hitCoords[0] = h->getX(); hitCoords[1] = h->getY(); - - genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), h->getSector(), ++hitId, nullptr); - planeId = h->getSector(); + /****************************************************************************************************************** + * If the Primary vertex is included + ******************************************************************************************************************/ + if ( true ) { + LOG_INFO << "Treating hit as a spacepoint" << endm; + if ( fh->isPV() ){ + LOG_DEBUG << "Including primary vertex in fit" << endm; + } + TVectorD pv(3); + pv[0] = h->getX(); + pv[1] = h->getY(); + pv[2] = h->getZ(); + LOG_INFO << "x = " << pv[0] << "+/- " << fh->_covmat(0,0) << ", y = " << pv[1] << " +/- " << fh->_covmat(1,1) << ", z = " << pv[2] << " +/- " << fh->_covmat(2,2) << endm; + auto tp = new genfit::TrackPoint(); + genfit::SpacepointMeasurement *measurement = new genfit::SpacepointMeasurement(pv, fh->_covmat, fh->_detid, ++hitId, tp); + tp->addRawMeasurement(measurement); + tp->setTrack(mFitTrack.get()); + if ( fh->isPV() ){ + tp->setSortingParameter(0); + } + if ( fh->isFtt() ){ + tp->setSortingParameter(4 + idxFtt); + idxFtt++; + } + if ( fh->isFst() ){ + tp->setSortingParameter(1 + idxFst); + idxFst++; + } + + mFitTrack->insertPoint( tp ); + continue; + } + + // if ( fh->isPV() ) continue; - if (mFTTPlanes.size() <= planeId) { - LOG_WARN << "invalid VolumId -> out of bounds DetPlane, vid = " << planeId << endm; - return TVector3(0, 0, 0); + genfit::PlanarMeasurement *measurement = new genfit::PlanarMeasurement(hitCoords, CovMatPlane(h), fh->_detid, ++hitId, nullptr); + + planeId = h->getSector(); + genfit::SharedPlanePtr plane; + if ( fh->isFtt() ){ + planeId = fh->_vid - 9; } + LOG_INFO << "planeId = " << planeId << ", sector " << h->getSector() << ", vid = " << fh->_vid << endm; + if (fh->isFtt() && mFTTPlanes.size() <= planeId) { + LOG_ERROR << "invalid VolumId -> out of bounds DetPlane, vid = " << dynamic_cast(h)->_vid << " vs. planeId = " << planeId << endm; + delete measurement; + continue; + } + + if (fh->isFtt()) + plane = mFTTPlanes[planeId]; + else if (fh->isFst()) + plane = getFstPlane( fh ); - auto plane = mFTTPlanes[planeId]; measurement->setPlane(plane, planeId); - fitTrack.insertPoint(new genfit::TrackPoint(measurement, &fitTrack)); + + mFitTrack->insertPoint(new genfit::TrackPoint(measurement, mFitTrack.get())); + LOG_INFO << "\tsetupTrack: Hit at Z = " << h->getZ() << " with plane at Z = " << plane->getO().Z() << endm; if (abs(h->getZ() - plane->getO().Z()) > 0.05) { LOG_WARN << "Z Mismatch h->z = " << h->getZ() << ", plane->z = "<< plane->getO().Z() <<", diff = " << abs(h->getZ() - plane->getO().Z()) << endm; } - } // loop on trackCand - + } // loop on trackSeed + } // setupTrack + /** @brief performs the fit on a track + * @param t : track to fit + */ + void performFit( std::shared_ptr t ){ /****************************************************************************************************************** * Do the fit ******************************************************************************************************************/ try { - // do the fit - mFitter->processTrackWithRep(&fitTrack, trackRepPos); - mFitter->processTrackWithRep(&fitTrack, trackRepNeg); - } catch (genfit::Exception &e) { - if (mGenHistograms) mHist["FitStatus"]->Fill("Exception", 1); - } + // prepare the track for fitting + // int nFailedPoints = 0; + // bool changed = false; + // changed = dynamic_cast( mFitter.get() )->prepareTrack( mFitTrack.get(), mFitTrack->getCardinalRep(), false, nFailedPoints); + // LOG_DEBUG << "Track prepared for fit with " << nFailedPoints << " failed points, changed? = " << changed << endm; - TVector3 p(0, 0, 0); + // check the track for consistency + mFitTrack->checkConsistency(); + // do the fit + mFitter->processTrack(t.get()); - /****************************************************************************************************************** - * Now check the fit - ******************************************************************************************************************/ - try { - //check - fitTrack.checkConsistency(); + // check the track for consistency + t->checkConsistency(); // find track rep with smallest chi2 - fitTrack.determineCardinalRep(); - auto cardinalRep = fitTrack.getCardinalRep(); - auto cardinalStatus = fitTrack.getFitStatus(cardinalRep); - mFitStatus = *cardinalStatus; // save the status of last fit - - // Delete any previous track rep - if (mTrackRep) - delete mTrackRep; - - // Clone the cardinal rep for persistency - mTrackRep = cardinalRep->clone(); // save the result of the fit - if (fitTrack.getFitStatus(cardinalRep)->isFitConverged() && mGenHistograms ) { - this->mHist["FitStatus"]->Fill("GoodCardinal", 1); + t->determineCardinalRep(); + // update the seed + // t->udpateSeed(); + + auto status = t->getFitStatus(); + LOG_INFO << "Fit status: " << status->isFitConverged() << endm; + LOG_INFO << "-Fit pvalue: " << status->getPVal() << endm; + LOG_INFO << "-Fit Chi2: " << status->getChi2() << endm; + + if ( status->isFitConverged() ){ + + auto cr = t->getCardinalRep(); + auto p = cr->getMom( t->getFittedState( 0, cr )); + int rcQ = status->getCharge(); + LOG_INFO << "Fit momentum: " << p.X() << ", " << p.Y() << ", " << p.Z() << endm; + LOG_INFO << "\tFit Pt: " << p.Pt() << ", eta: " << p.Eta() << ", phi: " << p.Phi() << endm; + // LOG_INFO << "\tMc Pt: " << mcMom.Pt() << ", eta: " << mcMom.Eta() << ", phi: " << mcMom.Phi() << endm; } - if (fitTrack.getFitStatus(trackRepPos)->isFitConverged() == false && - fitTrack.getFitStatus(trackRepNeg)->isFitConverged() == false) { - - LOG_WARN << "FWD Track GenFit Failed" << endm; - - p.SetXYZ(0, 0, 0); - long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) { - this->mHist["FitStatus"]->Fill("Fail", 1); - this->mHist["FailedFitDuration"]->Fill(duration); - } - return p; - } // neither track rep converged - - p = cardinalRep->getMom(fitTrack.getFittedState(1, cardinalRep)); - mQ = cardinalRep->getCharge(fitTrack.getFittedState(1, cardinalRep)); - mP = p; - - LOG_DEBUG << "track fit p = " << TString::Format( "(%f, %f, %f), q=%f", p.X(), p.Y(), p.Z(), mQ ).Data() << endm; } catch (genfit::Exception &e) { - LOG_WARN << "Exception on track fit: " << e.what() << endm; - p.SetXYZ(0, 0, 0); - - long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) { - this->mHist["FitStatus"]->Fill("Exception", 1); - this->mHist["FailedFitDuration"]->Fill(duration); - } - - return p; - } // try/catch - - long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds - if (mGenHistograms) { - this->mHist["FitStatus"]->Fill("Pass", 1); - this->mHist["delta_fit_seed_pT"]->Fill(p.Pt() - seedMom.Pt()); - this->mHist["delta_fit_seed_eta"]->Fill(p.Eta() - seedMom.Eta()); - this->mHist["delta_fit_seed_phi"]->Fill(p.Phi() - seedMom.Phi()); - this->mHist["FitDuration"]->Fill(duration); + LOG_ERROR << "Exception on fit update" << e.what() << endm; } - return p; + LOG_INFO << "Track fit update complete!" << endm; } - int getCharge() { - return (int)mQ; - } + /** + * @brief Primary track fitting routine + * + * @param trackSeed : + * @param Vertex : Primary Vertex + * @param seedMomentum : seed momentum (can be from MC) + * @return void : the results can be accessed via the getTrack() method + */ + long long fitTrack(Seed_t trackSeed, TVector3 *seedMomentum = 0) { + long long itStart = FwdTrackerUtils::nowNanoSecond(); + LOG_DEBUG << "Fitting track with " << trackSeed.size() << " FWD Measurements" << endm; + + /****************************************************************************************************************** + * First sort the seed, bc GENFIT seemingly cannot handle out of order points + ******************************************************************************************************************/ + std::sort(trackSeed.begin(), trackSeed.end(), + [](KiTrack::IHit *a, KiTrack::IHit *b) + { return a->getZ() < b->getZ(); } + ); + + /****************************************************************************************************************** + * Setup the track fit seed parameters and objects + ******************************************************************************************************************/ + setupTrack(trackSeed); + LOG_DEBUG << "Ready to fit with " << mFitTrack->getNumPoints() << " track points" << endm; - + /****************************************************************************************************************** + * Do the fit + ******************************************************************************************************************/ + performFit( mFitTrack ); + long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds + return duration; + } // fitTrack // Store the planes for FTT and FST vector mFTTPlanes; @@ -945,18 +507,12 @@ class TrackFitter { vector mFSTPlanesInner; vector mFSTPlanesOuter; - void SetIncludeVertex( bool vert ) { mIncludeVertexInFit = vert; } - protected: std::unique_ptr mBField; FwdTrackerConfig mConfig; // main config object TString mGeoCache; - // optional histograms, off by default - std::map mHist; - bool mGenHistograms = false; - // Main GenFit fitter instance std::unique_ptr mFitter = nullptr; @@ -972,20 +528,8 @@ class TrackFitter { // det z locations loaded from geom or config vector mFSTZLocations, mFTTZLocations; - // parameter ALIASED from mConfig wrt PV vertex - double mVertexSigmaXY = 1; - double mVertexSigmaZ = 30; - vector mVertexPos; - bool mIncludeVertexInFit = false; - - // GenFit state - genfit::FitStatus mFitStatus; - genfit::AbsTrackRep *mTrackRep; - genfit::Track *mFitTrack; - - // Fit results - TVector3 mP; - double mQ; + // GenFit state - resused + std::shared_ptr mFitTrack; }; #endif diff --git a/StRoot/StFwdTrackMaker/macro/build_geom.C b/StRoot/StFwdTrackMaker/macro/build_geom.C index f0fd5663882..327c9af71eb 100755 --- a/StRoot/StFwdTrackMaker/macro/build_geom.C +++ b/StRoot/StFwdTrackMaker/macro/build_geom.C @@ -2,7 +2,7 @@ // that is a valid shebang to run script as executable -void build_geom( TString geomtag = "dev2022", TString output="fGeom.root" ) { +void build_geom( TString geomtag = "y2023", TString output="fGeom.root" ) { gSystem->Load( "libStarRoot.so" ); @@ -21,7 +21,8 @@ void build_geom( TString geomtag = "dev2022", TString output="fGeom.root" ) { if ( 0 == geom ) { AgModule::SetStacker( new StarTGeoStacker() ); AgPosition::SetDebug(2); - StarGeometry::Construct("dev2022"); + cout << "Building geometry for tag [" << geomtag.Data() << "]" << endl; + StarGeometry::Construct( geomtag.Data() ); // Genfit requires the geometry is cached in a ROOT file gGeoManager->Export( output.Data() ); diff --git a/StRoot/StFwdTrackMaker/macro/daq/daq_track.C b/StRoot/StFwdTrackMaker/macro/daq/daq_track.C index 785b91ecbf5..c4bae46af5b 100755 --- a/StRoot/StFwdTrackMaker/macro/daq/daq_track.C +++ b/StRoot/StFwdTrackMaker/macro/daq/daq_track.C @@ -1,42 +1,79 @@ //usr/bin/env root4star -l -b -q $0; exit $? // that is a valid shebang to run script as executable -void daq_track( int n = 10, - const char *inFile = "input.daq", - std::string configFile = "daq/daq_track.xml", - const char *geom = "dev2022") { + +void daq_track( int n = 50, + const char *inFile = "st_fwd_23074018_raw_1000013.daq", + const char *geom = "y2023") { TString _chain; gSystem->Load( "libStarRoot.so" ); // Simplest chain with fst, fcs, ftt and fwdTracker - _chain = Form("in, %s, db, StEvent, MuDST, fcs, fst, ftt, fwdTrack", geom); - - // needed in this wonky spack environment + _chain = Form("in, %s, db, StEvent, trgd, btof, fcs, fst, ftt, fwdTrack, fstMuRawHit, EventQA, CMuDst, evout, tree", geom); + // _chain = Form("in, %s, StEvent, fcs, fst, ftt, fwdTrack, evout, tree", geom); + + // needed in this wonky spack environment / docker container gROOT->SetMacroPath(".:/star-sw/StRoot/macros:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); gROOT->LoadMacro("bfc.C"); bfc(-1, _chain, inFile); - // Extra configuration for the Forward Tracking - StFwdTrackMaker *fwdTrack = (StFwdTrackMaker*) chain->GetMaker("fwdTrack"); - if ( fwdTrack ){ //if it is in the chain - fwdTrack->SetConfigFile( configFile ); - // write debug histograms and ttree? - fwdTrack->SetGenerateTree( true ); - fwdTrack->SetGenerateHistograms( true ); - // write out wavefront OBJ files - fwdTrack->SetVisualize( false ); + + StFttClusterMaker *fttClu = (StFttClusterMaker*) chain->GetMaker("stgcCluster"); + if (fttClu){ + // fttClu->SetDebug(2); + fttClu->SetTimeCut( 1, -40, 40); + } + + StMaker * fwdMakerGen = chain->GetMaker("fwdTrack"); + if ( fwdMakerGen ){ + // Extra configuration for the Forward Tracking + StFwdTrackMaker *fwdTrack = (StFwdTrackMaker*) chain->GetMaker("fwdTrack"); + if ( fwdTrack ){ //if it is in the chain + cout << "Setting up Fwd Tracking in chain" << endl; + // fwdTrack->SetConfigFile( configFile ); + fwdTrack->setConfigForData(); + fwdTrack->setZeroB(); + fwdTrack->setSeedFindingWithFst(); + // write out wavefront OBJ files + fwdTrack->SetVisualize( false ); + fwdTrack->SetDebug(2); + fwdTrack->setTrackRefit(true); + fwdTrack->setGeoCache( "fGeom.root" ); + // fwdTrack->setDebug(); + + + } } + // The PicoDst + gSystem->Load("libStPicoEvent"); + gSystem->Load("libStPicoDstMaker"); + StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); + cout << "picoMk = " << picoMk << endl; + picoMk->setVtxMode(StPicoDstMaker::Default); + + // Generate FWD QA + StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); + fwdQAMk->SetDebug(2); + chain->AddAfter("fwdTrack", fwdQAMk); + + + + chain->Print(); // Initialize the chain chain->Init(); + // + //_____________________________________________________________________________ // // MAIN EVENT LOOP //_____________________________________________________________________________ for (int i = 0; i < n; i++) { chain->Clear(); + if ( fwdMakerGen ) + fwdMakerGen->SetDebug(1); if (kStOK != chain->Make()) break; } diff --git a/StRoot/StFwdTrackMaker/macro/daq/submit.xml b/StRoot/StFwdTrackMaker/macro/daq/submit.xml index 92676f3ff27..80111088e96 100644 --- a/StRoot/StFwdTrackMaker/macro/daq/submit.xml +++ b/StRoot/StFwdTrackMaker/macro/daq/submit.xml @@ -17,11 +17,6 @@ setup 64b starver dev - module use /cvmfs/star.sdcc.bnl.gov/star-spack/spack/share/spack/modules/linux-rhel7-x86_64/ - module load star-env-root-5.34.38 - module load kitrack-root-5.34.38 - module load genfit-root-5.34.38 - module load rave-2020-08-11 root4star -b -q -l 'daq/daq_track.C( 2, "'$INPUTFILE0'" )' diff --git a/StRoot/StFwdTrackMaker/macro/event/ana.C b/StRoot/StFwdTrackMaker/macro/event/ana.C new file mode 100755 index 00000000000..2a5861eb524 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/event/ana.C @@ -0,0 +1,42 @@ +//usr/bin/env root4star -l -b -q $0; exit $? +// that is a valid shebang to run script as executable + +void ana( int n = 5000, + const char *inFile = "sim.event.root", + const char *geom = "dev2022") { + TString _chain; + gSystem->Load( "libStarRoot.so" ); + + // Simplest chain with fst, fcs, ftt and fwdTracker + _chain = Form("in, %s, fcsdb, MakeEvent, CMuDst", geom); + + // needed in this wonky spack environment + gROOT->SetMacroPath(".:/star-sw/StRoot/macros:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + gSystem->Load("StFcsDbMaker.so"); + StFcsDbMaker* fcsdbmkr = (StFcsDbMaker*) chain->GetMaker("fcsDbMkr"); + cout << "fcsdbmkr="<GetDataSet("fcsDb"); + cout << "fcsdb="<Load("StFwdUtils.so"); + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(1); + + // Initialize the chain + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + chain->Clear(); + if (kStOK != chain->Make()) + break; + } +} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C b/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C new file mode 100644 index 00000000000..4e616a26997 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/mudst/fwdqa.C @@ -0,0 +1,137 @@ +//usr/bin/env root4star -l root -l -q $0; exit $? +// that is a valid shebang to run script as executable, but with only one arg + +void loadLibs(); +void fwdqa( const Char_t * fileList = "mudst.lis", int nEvents = 5000, int nFiles = 1 ){ + cout << "FileList: " << fileList << endl; + cout << "nFiles: " << nFiles << endl; + cout << "nEvents: " << nEvents << endl; + + // First load some shared libraries we need + loadLibs(); + + // create the chain + StChain *chain = new StChain("StChain"); + + // create the StMuDstMaker + StMuDstMaker *muDstMaker = new StMuDstMaker( 0, + 0, + "", + fileList, + "MuDst.root", + nFiles + ); + + // Initialize the database + // cout << endl << "============ Data Base =========" << endl; + // St_db_Maker *dbMk = new St_db_Maker("db","MySQL:StarDb","$STAR/StarDb","StarDb"); + + + // gSystem->Load("StFwdUtils.so"); + // StFwdAnalysisMaker * fwdAna = new StFwdAnalysisMaker(); + // fwdAna->setMuDstInput(); + // chain->AddMaker(fwdAna); + + // StFcsDbMaker * fcsDb = new StFcsDbMaker(); + // chain->AddMaker(fcsDb); + // fcsDb->SetDebug(); + + gSystem->Load("libStarGeneratorUtil.so"); + gSystem->Load("libgenfit2"); + gSystem->Load("libKiTrack"); + gSystem->Load( "StFwdTrackMaker.so" ); + gSystem->Load("libStEpdUtil.so"); + StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); + fwdQAMk->SetDebug(2); + + // Initialize chain + Int_t iInit = chain->Init(); + + cout << "CHAIN INIT DONE?" << endl; + // ensure that the chain initializes + if ( iInit ) + chain->Fatal(iInit,"on init"); + + // print the chain status + // chain->PrintInfo(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < nEvents; i++) { + chain->Clear(); + if (kStOK != chain->Make()) + break; + } + + // Chain Finish + if (nEvents > 1) { + cout << "FINISH up" << endl; + chain->Finish(); + } + + delete chain; + + + +} + + + +void loadLibs(){ + // if (gClassTable->GetID("TTable") < 0) { + // gSystem->Load("libStar"); + // gSystem->Load("libPhysics"); + // } + cout << "LL0" << endl; + gSystem->Load("libStarClassLibrary.so"); + gSystem->Load("libStarRoot.so"); + cout << "LL1" << endl; + gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + loadSharedLibraries(); + cout << "LL2" << endl; + + gSystem->Load("StarMagField"); + gSystem->Load("StMagF"); + gSystem->Load("StDetectorDbMaker"); + gSystem->Load("StTpcDb"); + gSystem->Load("StDaqLib"); + gSystem->Load("StDbBroker"); + gSystem->Load("StDbUtilities"); + gSystem->Load("St_db_Maker"); + + gSystem->Load("StEvent"); + gSystem->Load("StEventMaker"); + gSystem->Load("StarMagField"); + + gSystem->Load("libGeom"); + gSystem->Load("St_g2t"); + + // Added for Run16 And beyond + gSystem->Load("libGeom.so"); + + gSystem->Load("St_base.so"); + gSystem->Load("StUtilities.so"); + gSystem->Load("libPhysics.so"); + gSystem->Load("StarAgmlUtil.so"); + gSystem->Load("StarAgmlLib.so"); + gSystem->Load("libStarGeometry.so"); + gSystem->Load("libGeometry.so"); + + gSystem->Load("xgeometry"); + + gSystem->Load("St_geant_Maker"); + + + // needed since I use the StMuTrack + gSystem->Load("StarClassLibrary"); + gSystem->Load("StStrangeMuDstMaker"); + gSystem->Load("StMuDSTMaker"); + gSystem->Load("StBTofCalibMaker"); + gSystem->Load("StVpdCalibMaker"); + gSystem->Load("StBTofMatchMaker"); + gSystem->Load("StFcsDbMaker"); + + +} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/mudst.C b/StRoot/StFwdTrackMaker/macro/mudst/mudst.C new file mode 100755 index 00000000000..996397d87a6 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/mudst/mudst.C @@ -0,0 +1,130 @@ +//usr/bin/env root4star -l root -l -q $0; exit $? +// that is a valid shebang to run script as executable, but with only one arg + +void loadLibs(); +void mudst( const Char_t * fileList = "mudst.lis", int nEvents = 5000, int nFiles = 1 ){ + cout << "FileList: " << fileList << endl; + cout << "nFiles: " << nFiles << endl; + cout << "nEvents: " << nEvents << endl; + + // First load some shared libraries we need + loadLibs(); + + // create the chain + StChain *chain = new StChain("StChain"); + + // create the StMuDstMaker + StMuDstMaker *muDstMaker = new StMuDstMaker( 0, + 0, + "", + fileList, + "MuDst.root", + nFiles + ); + + // Initialize the database + // cout << endl << "============ Data Base =========" << endl; + // St_db_Maker *dbMk = new St_db_Maker("db","MySQL:StarDb","$STAR/StarDb","StarDb"); + + + gSystem->Load("StFwdUtils.so"); + StFwdAnalysisMaker * fwdAna = new StFwdAnalysisMaker(); + fwdAna->setMuDstInput(); + chain->AddMaker(fwdAna); + + StFcsDbMaker * fcsDb = new StFcsDbMaker(); + chain->AddMaker(fcsDb); + fcsDb->SetDebug(); + + + // Initialize chain + Int_t iInit = chain->Init(); + + cout << "CHAIN INIT DONE?" << endl; + // ensure that the chain initializes + if ( iInit ) + chain->Fatal(iInit,"on init"); + + // print the chain status + // chain->PrintInfo(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < nEvents; i++) { + chain->Clear(); + if (kStOK != chain->Make()) + break; + } + + // Chain Finish + if (nEvents > 1) { + cout << "FINISH up" << endl; + chain->Finish(); + } + + delete chain; + + + +} + + + +void loadLibs(){ + // if (gClassTable->GetID("TTable") < 0) { + // gSystem->Load("libStar"); + // gSystem->Load("libPhysics"); + // } + cout << "LL0" << endl; + gSystem->Load("libStarClassLibrary.so"); + gSystem->Load("libStarRoot.so"); + cout << "LL1" << endl; + gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + loadSharedLibraries(); + cout << "LL2" << endl; + + gSystem->Load("StarMagField"); + gSystem->Load("StMagF"); + gSystem->Load("StDetectorDbMaker"); + gSystem->Load("StTpcDb"); + gSystem->Load("StDaqLib"); + gSystem->Load("StDbBroker"); + gSystem->Load("StDbUtilities"); + gSystem->Load("St_db_Maker"); + + gSystem->Load("StEvent"); + gSystem->Load("StEventMaker"); + gSystem->Load("StarMagField"); + + gSystem->Load("libGeom"); + gSystem->Load("St_g2t"); + + // Added for Run16 And beyond + gSystem->Load("libGeom.so"); + + gSystem->Load("St_base.so"); + gSystem->Load("StUtilities.so"); + gSystem->Load("libPhysics.so"); + gSystem->Load("StarAgmlUtil.so"); + gSystem->Load("StarAgmlLib.so"); + gSystem->Load("libStarGeometry.so"); + gSystem->Load("libGeometry.so"); + + gSystem->Load("xgeometry"); + + gSystem->Load("St_geant_Maker"); + + + // needed since I use the StMuTrack + gSystem->Load("StarClassLibrary"); + gSystem->Load("StStrangeMuDstMaker"); + gSystem->Load("StMuDSTMaker"); + gSystem->Load("StBTofCalibMaker"); + gSystem->Load("StVpdCalibMaker"); + gSystem->Load("StBTofMatchMaker"); + gSystem->Load("StFcsDbMaker"); + + +} diff --git a/StRoot/StFwdTrackMaker/macro/mudst/pico.C b/StRoot/StFwdTrackMaker/macro/mudst/pico.C new file mode 100755 index 00000000000..7ff3f3a63ee --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/mudst/pico.C @@ -0,0 +1,602 @@ +//usr/bin/env root4star -l -b -q $0; exit $? +///////////////////////////////////////////////////////////////////////////// +// $Id: genDst.C,v 1.9 2020/10/10 07:16:56 genevb Exp $ +// Author: G. Van Buren (BNL) +// +// Description: +// Process a MuDst for... +// ...creating a PicoDst +// ...re-running vertex-finding to re-create MuDsts +// +// Options are space-separated or comma-separated, +// and case-insensitive. They can be attributed +// whose values are provided after a ':'. +// +// Example options for creating PicoDsts: +// picoDst +// btofMatch +// btofStartless +// mtdMatch +// y2017a +// +// Example lists of options: +// "picoDst" +// "DbV20200125,picoDst,mtdMatch,y2014a" +// +// Example options for vertex-finding: +// beamline, beamline1D, beamline3D (otherwise no beamline) +// useBTOFmatchOnly +// VFstore:100 +// +// Example lists of options: +// "VFPPVnoCTB,beamline1D,VFstore:100" +// "VFPPVnoCTB,beamline3D" +// +///////////////////////////////////////////////////////////////////////////// + +void afterburner(); + +void genDst(unsigned int Last, + const char* options, + char* infile, + char* outfile=0); + +void genDst(unsigned int First, + unsigned int Last, + const char* options, + char* infile, + char* outfile=0); + +void loadLibs() +{ + gROOT->Macro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + gSystem->Load("StDbBroker"); + gSystem->Load("St_db_Maker"); + gSystem->Load("StEEmcUtil"); +} + +void loadLibsVF() +{ + gSystem->Load("libMinuit"); + gSystem->Load("Sti"); + gSystem->Load("StBTofUtil"); + gSystem->Load("StGenericVertexMaker"); +} + +void loadLibsPico() +{ + + // EMCs and FMS need DB+converters + gSystem->Load("StEmcRawMaker"); + gSystem->Load("StEmcADCtoEMaker"); + gSystem->Load("StPreEclMaker"); + gSystem->Load("StEpcMaker"); + gSystem->Load("StEEmcDbMaker"); + gSystem->Load("StFmsUtil"); + gSystem->Load("StFmsDbMaker"); + gSystem->Load("StTriggerUtilities"); + + // The PicoDst + gSystem->Load("libStPicoEvent"); + gSystem->Load("libStPicoDstMaker"); +} + +void loadLibsAgML() +{ + // load support libraries. util will fail to load for agml 1.0, but you can ignore the error + gSystem->Load("libStarAgmlUtil"); + gSystem->Load("libStarAgmlLib"); + + // load geometry modules and master steering codes... + gSystem->Load("libGeometry"); + gSystem->Load("libStarGeometry"); +} + +void loadLibsMtd() +{ + gSystem->Load("StDetectorDbMaker"); + gSystem->Load("StarMagField"); + gSystem->Load("StMagF"); + gSystem->Load("StMtdUtil"); + gSystem->Load("StMtdMatchMaker"); + gSystem->Load("StMtdCalibMaker"); +} + +void loadLibsBTof() +{ + gSystem->Load("StBTofUtil"); + gSystem->Load("StVpdCalibMaker"); + gSystem->Load("StBTofCalibMaker"); + gSystem->Load("StBTofMatchMaker"); +} + +void loadLibsETof() +{ + gSystem->Load("StETofUtil"); + gSystem->Load("StETofCalibMaker"); + gSystem->Load("StETofHitMaker"); + gSystem->Load("StETofMatchMaker"); +} + +void loadLibsFwd() +{ + gSystem->Load("libStDetectorDbMaker.so"); + gSystem->Load("StEvent"); + gSystem->Load("StEventMaker"); + + // Fwd + gSystem->Load("StFwdUtils"); + gSystem->Load("libStarGeneratorUtil.so"); + gSystem->Load("libXMLIO"); + gSystem->Load("libgenfit2"); + gSystem->Load("libKiTrack"); + // gSystem->Load("StarGeneratorUtil") ; + gSystem->Load("libMathMore"); + gSystem->Load("StEventUtilities"); + gSystem->Load("StEpdUtil"); + gSystem->Load("StFwdTrackMaker"); + gSystem->Load("StFwdUtils"); + //Ftt + gSystem->Load("StFttDbMaker"); + gSystem->Load("StFttRawHitMaker"); + gSystem->Load("StFttHitCalibMaker"); + gSystem->Load("StFttClusterMaker"); + gSystem->Load("StFttPointMaker"); + // Fcs + gSystem->Load("libMinuit.so"); + gSystem->Load("StFcsDbMaker"); + gSystem->Load("StFcsRawHitMaker"); + gSystem->Load("StFcsWaveformFitMaker"); + gSystem->Load("StFcsClusterMaker"); + gSystem->Load("StFcsPointMaker"); + gSystem->Load("StFcsTrackMatchMaker"); + + // Fst + gSystem->Load("StFstUtil"); + gSystem->Load("StFstDbMaker"); + gSystem->Load("StFstRawHitMaker"); + gSystem->Load("StFstClusterMaker"); + gSystem->Load("StFstHitMaker"); +} + +void procGeoTag(TObjArray* optionTokens) +{ + if (TClass::GetClass("AgBlock")) return; // arbitrarily chosen AgML class + loadLibsAgML(); + + const char* tag = 0; + for (int tk=0; tk < optionTokens->GetEntries(); tk++) { + TString& tok = ((TObjString*) (optionTokens->At(tk)))->String(); + if (tok.BeginsWith("y20")){ + tag = tok.Data(); + optionTokens->RemoveAt(tk); + optionTokens->Compress(); + break; + } + } + + // Let agml know we want the ROOT geometry + AgModule::SetStacker( new StarTGeoStacker ); + + // now pass the geometry "tag" and build. If the class StarGeometry exists, we have + // AgML 2.0 and can run using the new steering. Otherwise, old steering codes... + if (tag) { + if ( TClass::GetClass("StarGeometry") ) { StarGeometry::Construct( tag ); } + else { ( new Geometry() )->ConstructGeometry(tag); } + } else { + gMessMgr->Warning() << "No geometry tag passed! (e.g. y2017a)" << endm; + } +} + +bool findAndRemoveOption(const char* optionName, TObjArray* optionTokens) +{ + TString optName = optionName; + optName.ToLower(); + TObject* obj = optionTokens->FindObject(optName.Data()); + if (obj) { + optionTokens->Remove(obj); + optionTokens->Compress(); + return true; + } + return false; +} + +void genDst(unsigned int First, + unsigned int Last, + const char* options, + char* infile, + char* outfile) +{ + loadLibs(); + + StChain fullChain("genDst"); + fullChain.SetDebug(1); + + StMuDstMaker muDstMaker(0, 0, "", infile, "st:MuDst.root", 1e9); // set up maker in read mode + // 0, 0 this means read mode + // dir read all files in this directory + // file bla.lis read all file in this list, if (file!="") dir is ignored + // filter apply filter to filenames, multiple filters are separated by ':' + // 10 maximum number of file to read + + + TChain& muDstChain = *muDstMaker.chain(); + unsigned int nEntries = muDstChain.GetEntries(); + unsigned int LastToRead = Last > 0 ? min(Last, nEntries) : nEntries; + gMessMgr->Info() << nEntries << " events in chain, " << LastToRead-First+1 << " will be read." << endm; + + // St_db_Maker* db = new St_db_Maker("db", "StarDb", "MySQL:StarDb", "$STAR/StarDb"); + + // Initialize some values and pointers + StMaker* processMaker = 0; + TFile* outFile = 0; + TTree* muDstTreeOut = 0; + + // Basic decisions based on options + TString CasedOptions = options; + TString Options = options; + Options.ToLower(); + TString optDelim = " ,"; + TObjArray* optionTokens = Options.Tokenize(optDelim); + optionTokens->SetOwner(kTRUE); + + // Determine database flavors + TString flavors = "ofl"; // default flavor for offline + + // simulation flavors + if (findAndRemoveOption("Simu",optionTokens) && ! findAndRemoveOption("NoSimuDb",optionTokens)) + flavors.Prepend("sim+"); + + // filestream flavors + TObject* firstFile = muDstChain.GetListOfFiles()->At(0); + if (firstFile) { + TString firstFileName = firstFile->GetTitle(); + firstFileName = firstFileName(firstFileName.Last('/')+1,firstFileName.Length()); + if (firstFileName.BeginsWith("st_")) { + TString fileStream = firstFileName(3,firstFileName.Index('_',3)-3); + if (fileStream.Length()>0) flavors.Prepend(fileStream += '+'); + } + } + + // gMessMgr->Info() << "Using DB flavors: " << flavors << endm; + // db->SetFlavor(flavors.Data()); + + if (findAndRemoveOption("picodst",optionTokens)) { + // _________________________________________________________________ + // Processing with generation of PicoDsts + + loadLibsPico(); + + // Specify active branches but first disable all branches + muDstMaker.SetStatus("*", 0); + muDstMaker.SetStatus("MuEvent", 1); + muDstMaker.SetStatus("PrimaryVertices", 1); + muDstMaker.SetStatus("PrimaryTracks", 1); + muDstMaker.SetStatus("GlobalTracks", 1); + muDstMaker.SetStatus("CovGlobTrack", 1); + muDstMaker.SetStatus("BTof*", 1); + muDstMaker.SetStatus("Emc*", 1); + muDstMaker.SetStatus("MTD*", 1); + muDstMaker.SetStatus("ETof*", 1); + muDstMaker.SetStatus("Epd*", 1); + muDstMaker.SetStatus("Fms*", 1); + muDstMaker.SetStatus("MCAll", 1); + muDstMaker.SetStatus("Fwd*", 1); + muDstMaker.SetStatus("Fcs*", 1); + muDstMaker.SetStatus("Ftt*", 1); + muDstMaker.SetStatus("Fst*", 1); + + // EMCs + // StEEmcDbMaker* eemcDb = new StEEmcDbMaker; + // StEmcADCtoEMaker* adc2e = new StEmcADCtoEMaker(); + // adc2e->saveAllStEvent(true); + // StPreEclMaker* pre_ecl = new StPreEclMaker(); + // StEpcMaker* epc = new StEpcMaker(); + + // FMS + // StFmsDbMaker* fmsDb = new StFmsDbMaker("fmsDb"); + + // Trigger simulator + // StTriggerSimuMaker* trigSimu = new StTriggerSimuMaker; + // trigSimu->setMC(false); + // trigSimu->useBemc(); + // trigSimu->useEemc(); + // trigSimu->useOfflineDB(); + // trigSimu->bemc->setConfig(StBemcTriggerSimu::kOffline); + + loadLibsFwd(); + + // If you need the geometry you can load it with this: + // gROOT->LoadMacro("/star-sw/StarVMC/Geometry/macros/loadStarGeometry.C"); + // loadStarGeometry( "y2023" ); + + // This makes the Fcs and Ftt hits show up in StEvent, + // and produces an StEvent for StFwdTracks to go into + StMuDst2StEventMaker * mu2ev = new StMuDst2StEventMaker(); + + // Re-run the FCS chain + StFcsDbMaker * fcsDbMk = new StFcsDbMaker(); + // StFcsWaveformFitMaker * fcsWFF = new StFcsWaveformFitMaker(); + // StFcsClusterMaker * fcsClu = new StFcsClusterMaker(); + // StFcsPointMaker * fcsPoint = new StFcsPointMaker(); + + // FTT chain + StFttDbMaker * fttDbMk = new StFttDbMaker(); + StFttHitCalibMaker * ftthcm = new StFttHitCalibMaker(); + StFttClusterMaker * fttclu = new StFttClusterMaker(); + fttclu->SetTimeCut(1, -40, 40); + StFttPointMaker * fttpoint = new StFttPointMaker(); + + + StFwdTrackMaker * fwdTrack = new StFwdTrackMaker(); + fwdTrack->setConfigForData( ); + fwdTrack->setGeoCache( "fGeom.root" ); + fwdTrack->setSeedFindingWithFst(); + fwdTrack->setIncludePrimaryVertexInFit(true); + fwdTrack->setMaxFailedHitsInFit(2); + fwdTrack->SetDebug(2); + + StFcsTrackMatchMaker *match = new StFcsTrackMatchMaker(); + match->setMaxDistance(6,10); + match->setFileName("fcstrk.root"); + match->SetDebug(); + + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(); + fwdAna->setLocalOutputFile( "StFwdAnalysisMaker.root"); + + StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); + fwdFitQA->SetDebug(); + + StFwdQAMaker *fwdQAMk = new StFwdQAMaker(); + fwdQAMk->SetDebug(2); + // chain->AddAfter("fwdTrack", fwdQAMk); + + if (findAndRemoveOption("btofmatch",optionTokens)) { + + procGeoTag(optionTokens); + loadLibsBTof(); + + // instantiate both VPD and BTOF CalibMakers and MatchMaker and point them to the MuDST + StBTofMatchMaker* btofMatch = new StBTofMatchMaker(); + btofMatch->setMuDstIn(); + StVpdCalibMaker *vpdCalib = new StVpdCalibMaker(); + vpdCalib->setMuDstIn(); + StBTofCalibMaker *btofCalib = new StBTofCalibMaker(); + btofCalib->setMuDstIn(); + + if (findAndRemoveOption("btofstartless",optionTokens)) { + //Disable the VPD as start detector, BTOF calib maker will switch to the "start-less" algorithm. + vpdCalib->setUseVpdStart(kFALSE); + } + + } + + if (findAndRemoveOption("etofmatch",optionTokens)) { + + procGeoTag(optionTokens); + loadLibsETof(); + + // instantiate eTOF CalibMakers, HitMaker and MatchMaker + StETofCalibMaker* etofCalib = new StETofCalibMaker(); + StETofHitMaker* etofHit = new StETofHitMaker(); + StETofMatchMaker* etofMatch = new StETofMatchMaker(); + + } + + if (findAndRemoveOption("mtdmatch",optionTokens)) { + + procGeoTag(optionTokens); + loadLibsMtd(); + + StMagFMaker* magfMk = new StMagFMaker; + StMtdMatchMaker* mtdMatchMaker = new StMtdMatchMaker(); + StMtdCalibMaker* mtdCalibMaker = new StMtdCalibMaker("mtdcalib"); + + } + + processMaker = (StMaker*) (new StPicoDstMaker(StPicoDstMaker::IoWrite, infile, "picoDst")); + StPicoDstMaker *picoMk = (StPicoDstMaker*) (processMaker); + picoMk->setVtxMode(StPicoDstMaker::Vpd); + gMessMgr->Info() << "PicoSetup Complete" << endm; + } else if (Options.Contains("fwd")) { + // _________________________________________________________________ + // Processing with new vertex-finding + + // loadLibsVF(); + + // Specify inactive branches but first enable all branches + muDstMaker.SetStatus("*",1); + muDstMaker.SetStatus("PrimaryTracks",0); + muDstMaker.SetStatus("PrimaryVertices",0); + + // Create new branch + // TClonesArray* verticesRefitted = new TClonesArray("StMuPrimaryVertex", 1000); + + // Specify output + if (outfile) { + outFile = new TFile(outfile, "RECREATE"); + } else { + // Use the same filename for output as was given by input + TString fileStr = infile; + Ssiz_t dir = fileStr.Last('/'); + if (dir<0) { + gMessMgr->Error() << "No specification for output when input is in local directory!" << endm; + return; + } + fileStr.Remove(0,dir+1); + outFile = new TFile(fileStr.Data(), "RECREATE"); + } + muDstTreeOut = muDstChain.CloneTree(0); + muDstTreeOut->Branch("PrimaryVertices", &verticesRefitted, 65536, 99); + + // processMaker = (StMaker*) (new StGenericVertexMaker()); + // processMaker->ToWhiteConst("vtxArray",verticesRefitted); + // processMaker->SetAttr("useMuDst",1); + + } else { + + gMessMgr->Info() << "No processing specified - just reading a MuDst?" << endm; + // User code may be inserted here + + } + + // Set additional options (except DbV) as maker attributes + if (processMaker) { + for (int tk=0; tk < optionTokens->GetEntries(); tk++) { + TString& Tag = ((TObjString*) (optionTokens->At(tk)))->String(); + + // copy of DbV code from StBFChain.cxx + if (Tag.BeginsWith("dbv")) { + int FDate=0,FTime=0; + if (Tag.Length() == 11) (void) sscanf(Tag.Data(),"dbv%8d",&FDate); + if (Tag.Length() == 18) (void) sscanf(Tag.Data(),"dbv%8d.%6d",&FDate,&FTime); + if (FDate) { + // db->SetMaxEntryTime(FDate,FTime); + // gMessMgr->Info() << "\tSet DataBase max entry time " << FDate << "/" << FTime + // << " for St_db_Maker(\"" << db->GetName() <<"\")" << endm; + } + continue; + } + + // assign attributes + StMaker* attrMaker = processMaker; + Ssiz_t delim = Tag.First(':'); + // look for "::" to set attributes for a different maker + if (delim > 0 && Tag[delim+1] == ':') { + TString altMakerName = Tag(0,delim); + // GetMaker...() functions are case sensitive, so find original case + Ssiz_t casedMakerNameIdx = CasedOptions.Index(altMakerName,0,TString::ECaseCompare::kIgnoreCase); + if (casedMakerNameIdx >= 0) altMakerName = CasedOptions(casedMakerNameIdx,delim); + StMaker* altMaker = fullChain.GetMaker(altMakerName.Data()); + if (!altMaker) altMaker = fullChain.GetMakerInheritsFrom(altMakerName.Data()); + if (!altMaker) { + gMessMgr->Warning() << "No maker found with name or class " << altMakerName.Data() << endm; + continue; + } + attrMaker = altMaker; + Tag.Remove(0,delim+2); + delim = Tag.First(':'); + } + if (delim < 0) { + attrMaker->SetAttr(Tag.Data(),1); + } else { + TString key(Tag(0,delim)); + TString& val = Tag.Remove(0,delim+1); + if (val.IsDigit()) { attrMaker->SetAttr(key.Data(),val.Atoi()); } + else if (val.IsFloat()) { attrMaker->SetAttr(key.Data(),val.Atof()); } + else { attrMaker->SetAttr(key.Data(),val.Data()); } + } + } + processMaker->PrintAttr(); + } + + { + TDatime t; + gMessMgr->QAInfo() << Form("Run is started at Date/Time %i/%i",t.GetDate(),t.GetTime()) << endm; + } + gMessMgr->QAInfo() << Form("Run on %s in %s",gSystem->HostName(),gSystem->WorkingDirectory()) << endm; + gMessMgr->QAInfo() << Form("with %s", fullChain.GetCVS()) << endm; + + gMessMgr->Info() << "Chain setup Complete" << endm; + + // Main loop over events + int iInit = fullChain.Init(); + if (iInit >= kStEOF) {fullChain.FatalErr(iInit,"on init"); return;} + if (Last == 0) return; + int eventCount = 0; + // Skip, if any + if (First > 1) fullChain.Skip(First - 1); + for (unsigned int iEvent = First; iEvent <= LastToRead; iEvent++) + { + // make an StEvent so that Fwd can save tracks, etc. + // StEvent * stEv = new StEvent(); + // fullChain.AddData( stEv ); + fullChain.SetDebug(2); + fwdTrack->SetDebug(2); + + int iMake = fullChain.Make(); + if (iMake) {fullChain.FatalErr(iMake,"on make"); return;} + + if (muDstTreeOut) muDstTreeOut->Fill(); + + int iClear = fullChain.Clear(); + if (iClear) {fullChain.FatalErr(iClear,"on clear"); return;} + eventCount++; + } + fullChain.Finish(); + + // + // ATTENTION - please DO NOT change the format of the next 2 lines, + // they are used by our DataManagement parsers to detect a generation + // was succesful and thereafter Catalog the produced files. + // Thank you. + // + gMessMgr->QAInfo() << "NumberOfEvents= " << eventCount << endm; + gMessMgr->QAInfo() << "Run completed " << endm; + + if (outFile) { + outFile->Write(); + outFile->Close(); + delete outFile; + } + + // delete db; + delete processMaker; + delete optionTokens; +} + +//__________________________________________________________ +void genDst(unsigned int Last, + const char* options, + char* infile, + char* outfile) +{ + cout << TString::Format("genDst( %u, '%s', '%s', '%s' )", Last, options, infile, outfile ) << endl; + genDst(1,Last,options,infile,outfile); +} + +void pico(){ + genDst(5000, "y2023a picodst PicoVtxMode:PicoVtxDefault", "/work/st_fwd_22355048_raw_1000012.MuDst.root", "PROD.root"); +} + +void pico( TString f, int n = 500){ + genDst(n, "y2023a picodst PicoVtxMode:PicoVtxDefault", f.Data(), "PROD.root" /*Not used?*/); +} + +///////////////////////////////////////////////////////////////////////////// +// +// $Log: genDst.C,v $ +// Revision 1.10 2022/05/12 07:16:56 weidenkaff +// Added eTOF support +// +// $Log: genDst.C,v $ +// Revision 1.9 2020/10/10 07:16:56 genevb +// Specify makers to set attributes +// +// Revision 1.8 2020/08/19 15:27:33 genevb +// Add DB flavors +// +// Revision 1.7 2020/01/25 05:10:00 genevb +// Include DbV, more like BFC +// +// Revision 1.6 2019/09/18 17:54:48 genevb +// Acivate additional branches by default +// +// Revision 1.5 2019/03/21 18:53:34 jeromel +// Added ATTENTION message +// +// Revision 1.4 2019/01/15 17:24:29 genevb +// Added FMS +// +// Revision 1.3 2018/03/16 18:41:14 genevb +// Add BTof-matching +// +// Revision 1.2 2017/12/15 18:36:53 genevb +// Remove explicit function of StPicoDstMaker...params should be passed by attribute +// +// Revision 1.1 2017/12/05 16:47:58 genevb +// Introduce genDst.C for creating new Dsts from MuDsts +// +// +///////////////////////////////////////////////////////////////////////////// diff --git a/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml b/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml new file mode 100644 index 00000000000..d6279fd1c97 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/mudst/submit_pico_run22pp.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + echo "JOBINDEX = ${JOBINDEX}" + echo "JOBID = ${JOBID}" + + ln -s StRoot/StFwdTrackMaker/macro/mudst/ mudst + ls -lah + + starver dev + root4star -b -q -l 'mudst/pico.C( "'$INPUTFILE0'", 50000 )' + + mv StFwdAnalysisMaker.root ${JOBID}_StFwdAnalysisMaker.root + mv StFwdFitQAMaker.root ${JOBID}_StFwdFitQAMaker.root + + + + + file:./StRoot + file:./fGeom.root + file:.sl73_gcc485/ + + + + + /gpfs01/star/pwg_tasks/FwdCalib/PROD/gen + + diff --git a/StRoot/StFwdTrackMaker/macro/qa/mudst.C b/StRoot/StFwdTrackMaker/macro/qa/mudst.C new file mode 100755 index 00000000000..966097b055b --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/qa/mudst.C @@ -0,0 +1,78 @@ +//usr/bin/env root4star -l -b -q $0'("'$1'")'; exit $? + +#include "TTree.h" +#include "TClonesArray.h" + +void mudst( TString df = "sim.MuDst.root" ){ + + // setup and make sure libraries are loaded + gSystem->Load( "libStarRoot.so" ); + gSystem->Load("libStarClassLibrary.so"); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + loadSharedLibraries(); + + gSystem->Load("libgenfit2.so"); + gSystem->Load("libKiTrack.so"); + gSystem->Load( "libStFwdTrackMaker.so" ); + + // now open our data file + TFile *f = new TFile(df); + TTree *t = (TTree*)f->Get("MuDst"); + + // create the readers for each branch + // TClonesArray *mcTracks = new TClonesArray("StMuMcTrack"); + // t->GetBranch("mcTracks")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("mcTracks",&mcTracks); + + // TClonesArray *fttPoints = new TClonesArray("StMuFttPoint"); + // t->GetBranch("fttPoints")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("fttPoints",&fttPoints); + + // TClonesArray *fttClusters = new TClonesArray("StMuFttCluster"); + // t->GetBranch("fttClusters")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("fttClusters",&fttClusters); + + // TClonesArray *fstPoints = new TClonesArray("StMuFstHit"); + // t->GetBranch("fstHits")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("fstHits",&fstPoints); + + // TClonesArray *wcal = new TClonesArray("FcsClusterWithStarXYZ"); + // t->GetBranch("wcalClusters")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("wcalClusters",&wcal); + + // TClonesArray *wcalHits = new TClonesArray("FcsHitWithStarXYZ"); + // t->GetBranch("wcalHits")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("wcalHits",&wcalHits); + + // TClonesArray *hcal = new TClonesArray("FcsClusterWithStarXYZ"); + // t->GetBranch("hcalClusters")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("hcalClusters",&hcal); + + // TClonesArray *hcalHits = new TClonesArray("FcsHitWithStarXYZ"); + // t->GetBranch("hcalHits")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("hcalHits",&hcalHits); + + // TClonesArray *epdHits = new TClonesArray("FcsHitWithStarXYZ"); + // t->GetBranch("epdHits")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("epdHits",&epdHits); + + TClonesArray *fwdTracks = new TClonesArray("StMuFwdTrack"); + t->GetBranch("FwdTrack")->SetAutoDelete(kFALSE); + t->SetBranchAddress("FwdTrack",&fwdTracks); + + // TClonesArray *seeds = new TClonesArray("StMuFwdTrackSeedPoint"); + // t->GetBranch("seeds")->SetAutoDelete(kFALSE); + // t->SetBranchAddress("seeds",&seeds); + + + //loop over the events + for ( int i = 0; i < t->GetEntries(); i++ ){ + t->GetEntry(i); + for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ + StMuFwdTrack *track = fwdTracks->At(j); + printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); + } + } + cout << "Processed: " << t->GetEntries() << " entries" << endl; +} \ No newline at end of file diff --git a/StRoot/StFwdTrackMaker/macro/qa/qa.C b/StRoot/StFwdTrackMaker/macro/qa/qa.C new file mode 100755 index 00000000000..926d9e1d472 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/qa/qa.C @@ -0,0 +1,281 @@ +//usr/bin/env root4star -l -b -q $0'("'"$1"'")'; exit $? + +#include "TTree.h" +#include "TClonesArray.h" +#include +// #include <__config> + +// TClonesArrays to read from the tree +TClonesArray *mcTracks = NULL; +TClonesArray *fttPoints = NULL; +TClonesArray *fttClusters = NULL; +TClonesArray *fstPoints = NULL; +TClonesArray *wcal = NULL; +TClonesArray *wcalHits = NULL; +TClonesArray *hcal = NULL; +TClonesArray *hcalHits = NULL; +TClonesArray *epdHits = NULL; +TClonesArray *fwdTracks = NULL; +TClonesArray *seeds = NULL; +TTree *t = NULL; + +std::map histograms; +TH1* addH1( string name, string title, int nx, float x1, float x2 ){ + histograms[name] = new TH1F( name.c_str(), title.c_str(), nx, x1, x2 ); + return histograms[name]; +} +TH2* addH2( string name, string title, int nx, float x1, float x2, int ny, float y1, float y2 ){ + histograms[name] = new TH2F( name.c_str(), title.c_str(), nx, x1, x2, ny, y1, y2 ); + return (TH2*)histograms[name]; +} +inline TH1 *getH1( string name ){ + // printf( "Looking for histogram name=[%s]", name.c_str() ); + assert( histograms.count( name ) && "Histogram cannot be found" && name.c_str() ); + assert( histograms[name] && TString::Format( "Histogram %s is NULL", name.c_str() ) ); + return histograms[name]; +} +inline TH2 *getH2( string name ){ + return (TH2*) getH1( name ); +} + +void setupRead( TString filename = "fwdtree.root" ){ + // setup and make sure libraries are loaded + gSystem->Load( "libStarRoot.so" ); + gSystem->Load("libStarClassLibrary.so"); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("$STAR/StRoot/StMuDSTMaker/COMMON/macros/loadSharedLibraries.C"); + loadSharedLibraries(); + + gSystem->Load("libgenfit2.so"); + gSystem->Load("libKiTrack.so"); + gSystem->Load( "libStFwdTrackMaker.so" ); + + // now open our data file + TFile *f = new TFile(filename); + t = (TTree*)f->Get("fwd"); + + // create the readers for each branch + mcTracks = new TClonesArray("StMuMcTrack"); + t->GetBranch("mcTracks")->SetAutoDelete(kFALSE); + t->SetBranchAddress("mcTracks",&mcTracks); + + fttPoints = new TClonesArray("StMuFttPoint"); + t->GetBranch("fttPoints")->SetAutoDelete(kFALSE); + t->SetBranchAddress("fttPoints",&fttPoints); + + fttClusters = new TClonesArray("StMuFttCluster"); + t->GetBranch("fttClusters")->SetAutoDelete(kFALSE); + t->SetBranchAddress("fttClusters",&fttClusters); + + fstPoints = new TClonesArray("StMuFstHit"); + t->GetBranch("fstHits")->SetAutoDelete(kFALSE); + t->SetBranchAddress("fstHits",&fstPoints); + + wcal = new TClonesArray("FcsClusterWithStarXYZ"); + t->GetBranch("wcalClusters")->SetAutoDelete(kFALSE); + t->SetBranchAddress("wcalClusters",&wcal); + + wcalHits = new TClonesArray("FcsHitWithStarXYZ"); + t->GetBranch("wcalHits")->SetAutoDelete(kFALSE); + t->SetBranchAddress("wcalHits",&wcalHits); + + hcal = new TClonesArray("FcsClusterWithStarXYZ"); + t->GetBranch("hcalClusters")->SetAutoDelete(kFALSE); + t->SetBranchAddress("hcalClusters",&hcal); + + hcalHits = new TClonesArray("FcsHitWithStarXYZ"); + t->GetBranch("hcalHits")->SetAutoDelete(kFALSE); + t->SetBranchAddress("hcalHits",&hcalHits); + + epdHits = new TClonesArray("FcsHitWithStarXYZ"); + t->GetBranch("epdHits")->SetAutoDelete(kFALSE); + t->SetBranchAddress("epdHits",&epdHits); + + fwdTracks = new TClonesArray("StMuFwdTrack"); + t->GetBranch("reco")->SetAutoDelete(kFALSE); + t->SetBranchAddress("reco",&fwdTracks); + + seeds = new TClonesArray("StMuFwdTrackSeedPoint"); + t->GetBranch("seeds")->SetAutoDelete(kFALSE); + t->SetBranchAddress("seeds",&seeds); +} + +void qaMomentumResolution(){ + + if ( histograms.count( "curveRcVsMc" ) == 0 ) { + printf( "Creating Momentum Resolution Histograms\n" ); + addH2( "curveRcVsMc", "Track curvature; MC; RC", 200, -10, 10, 200, -10, 10 ); + addH2( "curveMcVsPtMc", ";MC Pt; MC Curve ", 200, 0, 10, 100, 0, 10 ); + addH2( "ptRcVsMc", "Track Pt; MC; RC", 200, 0, 10, 200, 0, 10 ); + addH1( "curveRes", "Curvature Resolution; (C^{MC}-C^{RC})/C^{MC}", 200, -2, 2 ); + addH1( "transMomRes", "Pt Resolution; (Pt^{MC} - Pt^{RC}) / Pt^{MC}", 200, -2, 2 ); + addH1( "deltaCharge", "deltaCharge; |q_{MC}-q_{RC}|;counts;", 5, 0, 5 ); + } + + const TH2 * hCurveRcVsMc = getH2( "curveRcVsMc" ); + const TH2 * hCurveMcVsPtMc = getH2( "curveMcVsPtMc" ); + const TH2 * hPtRcVsMc = getH2( "ptRcVsMc" ); + + const TH1 * hCurveRes = getH1( "curveRes" ); + const TH1 * hTransMomRes = getH1( "transMomRes" ); + const TH1 * hDeltaCharge = getH1( "deltaCharge" ); + + for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ + + StMuFwdTrack *fwt = fwdTracks->At(j); + UShort_t indexToMatchedMC = fwt->idTruth() - 1; + // // cout << "Processing track " << j << ", mcid = " << indexToMatchedMC << endl; + if (indexToMatchedMC >= mcTracks->GetEntries()) continue; + // // get corresponding MC track + StMuMcTrack *mct = mcTracks->At(indexToMatchedMC); + + float curveMc = fabs(mct->Charge() / mct->pT()); + float curveRc = fabs(fwt->charge() / fwt->momentum().Pt()); + // // cout << "mct->pT() = " << mct->pT() << endl; + if ( mct->pT() > 0.1 && fwt->pval() > 0.01){ + hDeltaCharge->Fill( abs( mct->Charge() - fwt->charge() ) ); + hCurveRes->Fill( (curveMc - curveRc) / curveMc ); + hTransMomRes->Fill( (mct->pT() - fwt->momentum().Pt()) / mct->pT() ); + + hCurveRcVsMc->Fill( curveMc, curveRc ); + hCurveMcVsPtMc->Fill( curveMc, mct->pT() ); + hPtRcVsMc->Fill( mct->pT(), fwt->momentum().Pt() ); + } + } +} + +void qaFCSTrackMatch(){ + + if (histograms.count("dxWCAL") == 0){ + addH1( "dxWCAL", "WCAL; dx", 500, -100, 100 ); + addH1( "dxWCAL2", "WCAL; dx", 500, -100, 100 ); + addH1( "dyWCAL", "WCAL; dy", 500, -100, 100 ); + addH1( "dxHCAL", "HCAL; dx", 500, -100, 100 ); + addH1( "drWCAL", "WCAL; dr", 500, 0, 100 ); + addH1( "drHCAL", "HCAL; dr", 500, 0, 100 ); + addH2( "wcalTrackX", "; WCAL x; Track x", 500, -50, 50, 500, -50, 50 ); + addH2( "wcalTrackY", "; WCAL y; Track y", 500, -50, 50, 500, -50, 50 ); + } + + const TH1 * hdxWCAL = getH1("dxWCAL"); + const TH1 * hdxWCAL2 = getH1("dxWCAL2"); + const TH1 * hdyWCAL = getH1("dyWCAL"); + const TH1 * hdxHCAL = getH1("dxHCAL"); + + const TH1 * hdrWCAL = getH1("drWCAL"); + const TH1 * hdrHCAL = getH1("drHCAL"); + + const TH2 * hWCALX = getH1("wcalTrackX"); + const TH2 * hWCALY = getH1("wcalTrackY"); + + for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ + StMuFwdTrack *track = (StMuFwdTrack *)fwdTracks->At(j); + + // printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); + if ( track->pval() < 0.01 ) continue; + StMuFwdTrackProjection projWCAL; + track->getProjectionFor(kFcsWcalId, projWCAL); + // printf("Projection @ WCAL: det=%d, x=%f, y=%f, z=%f\n", projWCAL.mDetId, projWCAL.mXYZ.X(), projWCAL.mXYZ.Y(), projWCAL.mXYZ.Z()); + + StMuFwdTrackProjection projHCAL; + track->getProjectionFor(kFcsHcalId, projHCAL); + // printf("Projection @ HCAL: det=%d, x=%f, y=%f, z=%f\n", projHCAL.mDetId, projHCAL.mXYZ.X(), projHCAL.mXYZ.Y(), projHCAL.mXYZ.Z()); + + // loop over WCAL clusters + for ( int k = 0; k < wcal->GetEntries(); k++ ){ + FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); + double dx = projWCAL.mXYZ.X() - cluster->mXYZ.X(); + double dy = projWCAL.mXYZ.Y() - cluster->mXYZ.Y(); + double dr = sqrt( dx*dx + dy*dy ); + + hdxWCAL2->Fill( dx ); + if ( projWCAL.mXYZ.X() < 0 && cluster->mClu->detectorId() == 1 ) continue; + if ( projWCAL.mXYZ.X() > 0 && cluster->mClu->detectorId() == 0 ) continue; + + hdxWCAL->Fill( dx ); + hdyWCAL->Fill( dy ); + // printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); + hdrWCAL->Fill( dr ); + + hWCALX->Fill( cluster->mXYZ.X(), projWCAL.mXYZ.X() ); + hWCALY->Fill( cluster->mXYZ.Y(), projWCAL.mXYZ.Y() ); + } + + // loop over WCAL clusters + for ( int k = 0; k < hcal->GetEntries(); k++ ){ + FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)hcal->At(k); + double dx = projHCAL.mXYZ.X() - cluster->mXYZ.X(); + double dy = projHCAL.mXYZ.Y() - cluster->mXYZ.Y(); + double dr = sqrt( dx*dx + dy*dy ); + + hdxHCAL->Fill( dx ); + hdrHCAL->Fill( dr ); + } + + } +} + + +// Loop on events +void eventLoop( int numEventsLimit = -1, int reportEveryNthEvent = -1 ){ + int lastEventIndex = (numEventsLimit > 0 ? numEventsLimit : t->GetEntries() ); + for ( int i = 0; i < lastEventIndex; i++ ){ + t->GetEntry(i); + if ( reportEveryNthEvent > 0 && i % reportEveryNthEvent == 0){ + printf( "Processing Event %d...\n", i ); + } + // run qa subroutines here + // qaMomentumResolution(); + qaFCSTrackMatch(); + } +} + + + +void qa( TString filename = "fwdtree.root" ){ + setupRead( filename ); + TFile * fOut = new TFile( "QuickQA.root", "RECREATE" ); + fOut->cd(); + eventLoop(5000, 100); + fOut->Write(); + // writeHistograms(); + return; + //loop over the events + int nEvents = t->GetEntries(); + if (nEvents > 1000) nEvents = 1000; + for ( int i = 0; i < nEvents; i++ ){ + t->GetEntry(i); + for ( int j = 0; j < fwdTracks->GetEntries(); j++ ){ + StMuFwdTrack *track = fwdTracks->At(j); + printf("Track %d: pt=%f, eta=%f, phi=%f\n", j, track->momentum().Pt(), track->momentum().Eta(), track->momentum().Phi()); + + StMuFwdTrackProjection projWCAL; + track->getProjectionFor(kFcsWcalId, projWCAL); + printf("Projection @ WCAL: det=%d, x=%f, y=%f, z=%f\n", projWCAL.mDetId, projWCAL.mXYZ.X(), projWCAL.mXYZ.Y(), projWCAL.mXYZ.Z()); + + + StMuFwdTrackProjection projHCAL; + track->getProjectionFor(kFcsHcalId, projHCAL); + printf("Projection @ HCAL: det=%d, x=%f, y=%f, z=%f\n", projHCAL.mDetId, projHCAL.mXYZ.X(), projHCAL.mXYZ.Y(), projHCAL.mXYZ.Z()); + + // loop over WCAL clusters + for ( int k = 0; k < wcal->GetEntries(); k++ ){ + FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); + + printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); + + } + + + // loop over WCAL clusters + for ( int k = 0; k < wcal->GetEntries(); k++ ){ + FcsClusterWithStarXYZ *cluster = (FcsClusterWithStarXYZ*)wcal->At(k); + + printf("WCAL Cluster %d: x=%f, y=%f, z=%f\n", k, cluster->mXYZ.X(), cluster->mXYZ.Y(), cluster->mXYZ.Z()); + + } + + } + } + cout << "Processed: " << t->GetEntries() << " entries" << endl; +} diff --git a/StRoot/StFwdTrackMaker/macro/sim/close.C b/StRoot/StFwdTrackMaker/macro/sim/close.C new file mode 100755 index 00000000000..5ee794cf871 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/close.C @@ -0,0 +1,108 @@ +//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-50}','${3:-0.001}','${4:-0.001}','${5:-3.0}','${6:-0.004}','${7:-0}',"'${8:- }'")'; exit $? +// that is a valid shebang to run script as executable, but with only one arg + + +// Run very fast fwd tracking +// generate some input data using genfzd + +TFile *output = 0; + +void close( char *inFile = "sim.fzd", + int n = 100000, // nEvents to run + double primaryVertexSigmaXY = 0.001, + double primaryVertexSigmaZ = 0.001, + double fstRasterR = 3.0, + double fstRasterPhi = 0.0040906154, + int numFttToUse = 0, + TString note = "" + ) { + // report all of the parameters passed in + cout << "inFile = " << inFile << endl; + cout << "nEvents = " << n << endl; + TString mOutput = TString::Format( + "closure_PV_XY%dum_Z%dum_FST_R%.2fcm_PHI%0.3frad_NumFTT%d%s", + (int)(primaryVertexSigmaXY*1e4), + (int)(primaryVertexSigmaZ*1e4), + fstRasterR, + fstRasterPhi, + numFttToUse, + note.Data() + ); + // replace all "." with "p" in the output file name + mOutput.ReplaceAll(".", "p"); + mOutput += ".root"; + cout << "Output file = " << mOutput.Data() << endl; + + // Setup the chain for reading an FZD + TString _chain; + _chain = "fzin sdt20211016 MakeEvent bigbig evout cmudst tree"; + + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + gSystem->Load( "libStFttSimMaker" ); + gSystem->Load( "libStFcsTrackMatchMaker" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libStarGeneratorUtil" ); + + gSystem->Load("libXMLIO.so"); + gSystem->Load("libgenfit2.so"); + gSystem->Load("libKiTrack.so"); + gSystem->Load("StarGeneratorUtil"); + // gSystem->Load("libMathMore.so"); + gSystem->Load("StEventUtilities"); + gSystem->Load("StEpdUtil"); + gSystem->Load("StFwdTrackMaker"); + + gSystem->Load("StFwdUtils.so"); + + + // Configure the Forward Tracker + StFwdClosureMaker * fwdClosure = new StFwdClosureMaker(); + fwdClosure->SetDebug(1); + fwdClosure->mMaxIt = 4; + + fwdClosure->mBlowUp = 1e3; + fwdClosure->mPVal = 1e-3; + fwdClosure->mRelChi2 = 1e-3; + + fwdClosure->mFttMode = StFwdClosureMaker::kStrip; + + fwdClosure->mPrimaryVertexSigXY = primaryVertexSigmaXY; + fwdClosure->mPrimaryVertexSigZ = primaryVertexSigmaZ; + fwdClosure->mRasterR = fstRasterR; + fwdClosure->mRasterPhi = fstRasterPhi; + fwdClosure->mNumFttToUse = numFttToUse; + fwdClosure->mOutFile = mOutput; + fwdClosure->SetDebug(1); + + chain->AddBefore("MuDst", fwdClosure); + + + StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); + + // if (muDstMaker){ + // StFwdQAMaker *fwdQA = new StFwdQAMaker(); + // fwdQA->SetDebug(2); + // chain->AddAfter("MuDst", fwdQA); + // } + +chain_loop: + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + cout << "--------->START EVENT: " << i << endl; + chain->Clear(); + if (kStOK != chain->Make()) + break; + cout << "<---------- END EVENT" << endl; + } // event loop +} diff --git a/StRoot/StFwdTrackMaker/macro/sim/fast.C b/StRoot/StFwdTrackMaker/macro/sim/fast.C new file mode 100755 index 00000000000..7cfc9ba7357 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/fast.C @@ -0,0 +1,145 @@ +//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-5}')'; exit $? +// that is a valid shebang to run script as executable, but with only one arg + + +// Run very fast fwd tracking +// generate some input data using genfzd + +TFile *output = 0; + +void fast( char *inFile = "sim.fzd", + int n = 1000, // nEvents to run + bool useFstForSeedFinding = true, // use FTT (default) or FST for track finding + bool enableTrackRefit = true, // Enable track refit (default off) + bool realisticSim = true, // enables data-like mode, real track finding and fitting without MC seed + bool useZeroB = false + ) { + // report all of the parameters passed in + cout << "inFile = " << inFile << endl; + cout << "n = " << n << endl; + cout << "useFstForSeedFinding = " << useFstForSeedFinding << endl; + cout << "enableTrackRefit = " << enableTrackRefit << endl; + cout << "realisticSim = " << realisticSim << endl; + cout << "useZeroB = " << useZeroB << endl; + const char *geom = ""; + TString _geom = geom; + + // Switches for common options + bool SiIneff = false; + bool useConstBz = false; + bool useFCS = true; + + // to use the geom cache (skip agml build which is faster) + // set the _geom string to "" and make sure the cache file ("fGeom.root") is present + // _geom = ""; + + // Setup the chain for reading an FZD + TString _chain; + + _chain = Form("fzin %s sdt20211016 fwdTrack MakeEvent bigbig evout cmudst tree", _geom.Data() ); + + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + gSystem->Load( "libStFttSimMaker" ); + gSystem->Load( "libStFcsTrackMatchMaker" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libStarGeneratorUtil" ); + + + gSystem->Load("StFwdUtils.so"); + + + + // Configure the Forward Tracker + StFwdTrackMaker * fwdTrack = (StFwdTrackMaker*) chain->GetMaker( "fwdTrack" ); + + if ( fwdTrack ){ + fwdTrack->SetDebug(1); + // config file set here for ideal simulation + if (!realisticSim){ + cout << "Configured for ideal simulation (MC finding + MC mom seed)" << endl; + fwdTrack->setConfigForIdealSim( ); + } else { + cout << "Configured for realistic simulation" << endl; + fwdTrack->setConfigForRealisticSim( ); + cout << "Configured for realistic simulation DONE" << endl; + } + + if ( _geom == "" ){ + cout << "Using the Geometry cache: fGeom.root" << endl; + fwdTrack->setGeoCache( "fGeom.root" ); + } + + // choose + if (useFstForSeedFinding) + fwdTrack->setSeedFindingWithFst(); + else { // default for this true/false option + fwdTrack->setSeedFindingWithFtt(); + } + // other options + // fwdTrack->setSeedFindingWithFtt(); + // fwdTrack->setSeedFindingWithFstFttSequential(); + // fwdTrack->setSeedFindingWithFstFttSimultaneous(); + + + fwdTrack->setOutputFilename( TString::Format( "%s.output.root", inFile ).Data() ); + fwdTrack->SetVisualize( false ); + fwdTrack->SetDebug(); + fwdTrack->setTrackRefit( enableTrackRefit ); + fwdTrack->setConstB( useConstBz ); + + if ( useZeroB ){ + cout << "Setting B = 0" << endl; + fwdTrack->setZeroB( true ); + } + + bool doFitQA = true; + if ( doFitQA ){ + StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); + fwdFitQA->SetDebug(); + TString fitqaoutname(gSystem->BaseName(inFile)); + fitqaoutname.ReplaceAll(".fzd", ".FwdFitQA.root"); + fwdFitQA->setOutputFilename( fitqaoutname ); + chain->AddAfter("fwdTrack", fwdFitQA); + } + cout << "fwd tracker setup" << endl; + } + + StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); + + if (muDstMaker){ + StFwdQAMaker *fwdQA = new StFwdQAMaker(); + fwdQA->SetDebug(2); + TString fwdqaname(gSystem->BaseName(inFile)); + fwdqaname.ReplaceAll(".fzd", ".FwdTree.root"); + fwdQA->setTreeFilename(fwdqaname); + chain->AddAfter("MuDst", fwdQA); + } + + // The PicoDst + gSystem->Load("libStPicoEvent"); + gSystem->Load("libStPicoDstMaker"); + StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); + cout << "picoMk = " << picoMk << endl; + picoMk->setVtxMode(StPicoDstMaker::Default); + +chain_loop: + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + cout << "--------->START EVENT: " << i << endl; + chain->Clear(); + if (kStOK != chain->Make()) + break; + cout << "<---------- END EVENT" << endl; + } // event loop +} diff --git a/StRoot/StFwdTrackMaker/macro/sim/gen.C b/StRoot/StFwdTrackMaker/macro/sim/gen.C old mode 100644 new mode 100755 index 5056662f861..b5d2b16ba43 --- a/StRoot/StFwdTrackMaker/macro/sim/gen.C +++ b/StRoot/StFwdTrackMaker/macro/sim/gen.C @@ -1,3 +1,4 @@ +//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? // macro to instantiate the Geant3 from within // STAR C++ framework and get the starsim prompt // To use it do @@ -18,7 +19,24 @@ StarKinematics *kinematics = 0; TH1F* hNumHits = 0; TString nameParticle = "mu+"; -float numParticles = 5; +int numParticles = 1; +float minPt = 0.0; +float maxPt = 1.0; +float minEta = 2.5; +float maxEta = 4.00; +float minPhi = 0.0; +float maxPhi = 2.0 * TMath::Pi(); + +float vtxX = 0.0; +float vtxY = 0.0; +float vtxZ = 0.0; + +float vtxSigmaX = 0.0001; +float vtxSigmaY = 0.0001; +float vtxSigmaZ = 0.0001; + +TString fzdFilename = "sim.fzd"; +TString primaryName = "sim.root"; // ---------------------------------------------------------------------------- void geometry( TString tag, Bool_t agml=true ) @@ -35,58 +53,46 @@ void command( TString cmd ) geant_maker -> Do( cmd ); } // ---------------------------------------------------------------------------- +void trig_event( Int_t i ) +{ + if ( gRandom->Rndm() > 0.5 ) { + nameParticle = "mu+"; + } else { + nameParticle = "mu-"; + } + kinematics->Kine( numParticles, nameParticle.Data(), minPt, maxPt, minEta, maxEta, minPhi, maxPhi ); +} +// ---------------------------------------------------------------------------- void trig( Int_t n=1 ) { - - for ( Int_t i=0; iClear(); - - kinematics->Kine( numParticles, nameParticle.Data(), 0.2, 5.0, 2.0, 4.50 ); - // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); - + trig_event( i ); // Generate the event chain->Make(); - - TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); - if ( hits ) { - double nhits = hits->GetNRows(); - hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); - std::cout << "N hits = " << nhits << std::endl; - } - - // Print the event - // command("gprint hits stgh"); - } } // ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- void Kinematics() { - + // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); gSystem->Load( "libKinematics.so"); kinematics = new StarKinematics(); - _primary->AddGenerator(kinematics); } // ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) -{ +void gen( Int_t nevents=1000, Int_t rngSeed=12352342 ) +{ - cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; + cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; gSystem->Load( "libStarRoot.so" ); gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); gROOT->ProcessLine(".L bfc.C"); { - TString simple = "sdt20211016 y2023 geant gstar usexgeom agml "; + TString simple = "sdt20211016 y2024 geant gstar usexgeom agml "; bfc(0, simple ); } @@ -96,7 +102,7 @@ void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) gSystem->Load( "StarGeneratorEvent.so" ); gSystem->Load( "StarGeneratorBase.so" ); - gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libMathMore.so" ); gSystem->Load( "xgeometry.so" ); // Setup RNG seed and map all ROOT TRandom here @@ -110,7 +116,7 @@ void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) // StarPrimaryMaker * _primary = new StarPrimaryMaker(); { - _primary -> SetFileName( "sim.root"); + _primary -> SetFileName( primaryName ); chain -> AddBefore( "geant", _primary ); } @@ -120,19 +126,15 @@ void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) // Initialize primary event generator and all sub makers // _primary -> Init(); - _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex - _primary->SetVertex(0.0, 0.0, 0.0 ); + _primary->SetSigma( vtxSigmaX, vtxSigmaY, vtxSigmaZ ); // 1mm x 1mm x 1mm smearing at the vertex + _primary->SetVertex(vtxX, vtxY, vtxZ ); // // Setup geometry and set starsim to use agusread for input // //geometry("y2012"); command("gkine -4 0"); - command("gfile o sim.fzd"); - - - hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); - // hNumHits->SetBit(TH1::kCanRebin); + command( TString::Format("gfile o %s", fzdFilename.Data()) ); // command( "DCAY 0" ); @@ -150,19 +152,14 @@ void gen( Int_t nevents=100, Int_t rngSeed=12352342 ) // command( "MULS 0" ); // command( "STRA 0" ); // command( "physi" ); - + // // Trigger on nevents // + // StarMagField::setConstBz(true); trig( nevents ); - // TFile * f = new TFile( "gen.root", "RECREATE" ); - // f->cd(); - // hNumHits->Write(); - // f->Write(); - command("call agexit"); // Make sure that STARSIM exits properly } // ---------------------------------------------------------------------------- - diff --git a/StRoot/StFwdTrackMaker/macro/sim/jpsi.C b/StRoot/StFwdTrackMaker/macro/sim/jpsi.C new file mode 100755 index 00000000000..bc4f936d29e --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/jpsi.C @@ -0,0 +1,225 @@ +//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? +// macro to instantiate the Geant3 from within +// STAR C++ framework and get the starsim prompt +// To use it do +// root4star starsim.C + +class St_geant_Maker; +St_geant_Maker *geant_maker = 0; + +class StarGenEvent; +StarGenEvent *event = 0; + +class StarPrimaryMaker; +StarPrimaryMaker *_primary = 0; + +class StarKinematics; +StarKinematics *kinematics = 0; + + +TH1F* hMll = 0; +bool decayJPsiToElectrons = false; +float numParticles = 1; + +// ---------------------------------------------------------------------------- +void geometry( TString tag, Bool_t agml=true ) +{ + TString cmd = "DETP GEOM "; cmd += tag + " field=-5.0"; + if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); + geant_maker -> LoadGeometry(cmd); + // if ( agml ) command("gexec $STAR_LIB/libxgeometry.so"); +} +// ---------------------------------------------------------------------------- +void command( TString cmd ) +{ + if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); + geant_maker -> Do( cmd ); +} +// ---------------------------------------------------------------------------- +void trig( Int_t n=1 ) +{ + + + for ( Int_t i=0; iClear(); + + //(Momentum, Energy units are Gev/C, GeV) + Double_t masses[2] = { 0.00051099895000, 0.00051099895000} ; + + if (!decayJPsiToElectrons){ + masses[0] = 0.1056583755; + masses[1] = 0.1056583755; + } + + TGenPhaseSpace genEvent; + TLorentzVector W; + // W.SetPtEtaPhiM( 0.0, 100.0, 0, 3.096 ); + W.SetXYZM( 0, 0, 30, 3.096 ); + genEvent.SetDecay(W, 2, masses); + + TLorentzVector lv; + for ( int j = 0; j < numParticles; j++ ){ + Double_t weight = genEvent.Generate(); + TLorentzVector *pElectron = genEvent.GetDecay(0); + TLorentzVector *pPositron = genEvent.GetDecay(1); + lv = *pElectron + *pPositron; + + StarGenParticle *ele; + if ( decayJPsiToElectrons ) + ele = kinematics->AddParticle( "e-" ); + else + ele = kinematics->AddParticle( "mu-" ); + ele->SetPx(pElectron->Px()); + ele->SetPy(pElectron->Py()); + ele->SetPz(pElectron->Pz()); + ele->SetMass( masses[0] ); + + StarGenParticle *pos; + if ( decayJPsiToElectrons ) + pos = kinematics->AddParticle( "e+" ); + else + pos = kinematics->AddParticle( "mu+" ); + pos->SetPx(pPositron->Px()); + pos->SetPy(pPositron->Py()); + pos->SetPz(pPositron->Pz()); + pos->SetMass( masses[0] ); + + hMll->Fill( lv.M() ); + + cout << "ele eta = " << pElectron->Eta() << endl; + cout << "pos eta = " << pPositron->Eta() << endl; + } + + + // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); + + // Generate the event + chain->Make(); + + // TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); + // if ( hits ) { + // double nhits = hits->GetNRows(); + // hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); + // std::cout << "N hits = " << nhits << std::endl; + // } + + // Print the event + // command("gprint hits stgh"); + + } +} +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void Kinematics() +{ + + // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); + gSystem->Load( "libKinematics.so"); + kinematics = new StarKinematics(); + + _primary->AddGenerator(kinematics); +} +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void jpsi( Int_t nevents=10000, Int_t rngSeed=12352342, bool decayToElectrons = true ) +{ + + hMll = new TH1F("hMll",";Mll;counts [10MeV]", 200, 2.0, 4.0 ); + decayJPsiToElectrons = decayToElectrons; + cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; + if ( decayToElectrons ){ + cout << "Simulating J/psi->e+e-" << endl; + } else { + cout << "Simulating J/psi->mu+mu-" << endl; + } + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + + gROOT->ProcessLine(".L bfc.C"); + { + TString simple = "sdt20211016 y2024 geant gstar usexgeom agml "; + bfc(0, simple ); + } + + gSystem->Load( "libVMC.so"); + + gSystem->Load( "StarGeneratorUtil.so" ); + gSystem->Load( "StarGeneratorEvent.so" ); + gSystem->Load( "StarGeneratorBase.so" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "xgeometry.so" ); + + + + // Setup RNG seed and map all ROOT TRandom here + StarRandom::seed( rngSeed ); + StarRandom::capture(); + + // + // Create the primary event generator and insert it + // before the geant maker + // + // StarPrimaryMaker * + _primary = new StarPrimaryMaker(); + { + _primary -> SetFileName( "jpsi.root"); + chain -> AddBefore( "geant", _primary ); + } + + Kinematics(); + + // + // Initialize primary event generator and all sub makers + // + _primary -> Init(); + _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex + _primary->SetVertex(0.0, 0.0, 0.0 ); + + // + // Setup geometry and set starsim to use agusread for input + // + //geometry("y2012"); + command("gkine -4 0"); + command("gfile o jpsi.fzd"); + + + hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); + // hNumHits->SetBit(TH1::kCanRebin); + + + // command( "DCAY 0" ); + // command( "ANNI 0" ); + // command( "BREM 0" ); + // command( "COMP 0" ); + // command( "HADR 0" ); + // command( "MUNU 0" ); + // command( "PAIR 0" ); + // command( "PFIS 0" ); + // command( "PHOT 0" ); + // command( "RAYL 0" ); + // command( "LOSS 4" ); + // command( "DRAY 0" ); + // command( "MULS 0" ); + // command( "STRA 0" ); + // command( "physi" ); + + // + // Trigger on nevents + // + trig( nevents ); + + TFile * f = new TFile( "jpsi_gen.root", "RECREATE" ); + f->cd(); + hMll->Write(); + f->Write(); + + command("call agexit"); // Make sure that STARSIM exits properly + +} +// ---------------------------------------------------------------------------- + diff --git a/StRoot/StFwdTrackMaker/macro/sim/lambda.C b/StRoot/StFwdTrackMaker/macro/sim/lambda.C new file mode 100755 index 00000000000..23af6349857 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/lambda.C @@ -0,0 +1,191 @@ +//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? +// macro to instantiate the Geant3 from within +// STAR C++ framework and get the starsim prompt +// To use it do +// root4star starsim.C + +class St_geant_Maker; +St_geant_Maker *geant_maker = 0; + +class StarGenEvent; +StarGenEvent *event = 0; + +class StarPrimaryMaker; +StarPrimaryMaker *_primary = 0; + +class StarKinematics; +StarKinematics *kinematics = 0; + + +TH1F* hMll = 0; +float numParticles = 1; + +// ---------------------------------------------------------------------------- +void geometry( TString tag, Bool_t agml=true ) +{ + TString cmd = "DETP GEOM "; cmd += tag + " field=-5.0"; + if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); + geant_maker -> LoadGeometry(cmd); + // if ( agml ) command("gexec $STAR_LIB/libxgeometry.so"); +} +// ---------------------------------------------------------------------------- +void command( TString cmd ) +{ + if ( !geant_maker ) geant_maker = (St_geant_Maker *)chain->GetMaker("geant"); + geant_maker -> Do( cmd ); +} +// ---------------------------------------------------------------------------- +void trig( Int_t n=1 ) +{ + + + for ( Int_t i=0; iClear(); + + //(Momentum, Energy units are Gev/C, GeV) + Double_t masses[2] = { 0.13957, 0.938} ; + + TGenPhaseSpace genEvent; + TLorentzVector W; + // W.SetPtEtaPhiM( 0.0, 100.0, 0, 3.096 ); + W.SetXYZM( 0, 0, 5, 1.11568 ); + genEvent.SetDecay(W, 2, masses); + + TLorentzVector lv; + for ( int j = 0; j < numParticles; j++ ){ + Double_t weight = genEvent.Generate(); + TLorentzVector *pPion = genEvent.GetDecay(0); + TLorentzVector *pProton = genEvent.GetDecay(1); + lv = *pPion + *pProton; + + StarGenParticle *pion; + pion = kinematics->AddParticle( "pi-" ); + + pion->SetPx(pPion->Px()); + pion->SetPy(pPion->Py()); + pion->SetPz(pPion->Pz()); + pion->SetMass( masses[0] ); + + StarGenParticle *proton; + proton = kinematics->AddParticle( "p" ); + + + proton->SetPx(pProton->Px()); + proton->SetPy(pProton->Py()); + proton->SetPz(pProton->Pz()); + proton->SetMass( masses[1] ); + + hMll->Fill( lv.M() ); + + cout << "pion eta = " << pPion->Eta() << endl; + cout << "proton eta = " << pProton->Eta() << endl; + } + + + // kinematics->Kine( numParticles, nameParticle.Data(), 10.2, 12.0, 2.5, 4.00 ); + + // Generate the event + chain->Make(); + + // TTable* hits = chain->GetDataSet("bfc/.make/geant/.data/g2t_stg_hit"); + // if ( hits ) { + // double nhits = hits->GetNRows(); + // hNumHits->Fill( double(i), nhits / 4.0 / numParticles ); + // std::cout << "N hits = " << nhits << std::endl; + // } + + // Print the event + // command("gprint hits stgh"); + + } +} +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void Kinematics() +{ + + // gSystem->Load( "libStarGeneratorPoolPythia6_4_23.so" ); + gSystem->Load( "libKinematics.so"); + kinematics = new StarKinematics(); + + _primary->AddGenerator(kinematics); +} +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +void lambda( Int_t nevents=100, Int_t rngSeed=12352342 ) +{ + hMll = new TH1F("hMll",";Mll;counts [10MeV]", 200, 2.0, 4.0 ); + cout << "Generating: " << nevents << " events with seed: " << rngSeed << endl; + cout << "Simulating J/psi->e+e-" << endl; + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + + gROOT->ProcessLine(".L bfc.C"); + { + TString simple = "sdt20211016 y2023 geant gstar usexgeom agml "; + bfc(0, simple ); + } + + gSystem->Load( "libVMC.so"); + + gSystem->Load( "StarGeneratorUtil.so" ); + gSystem->Load( "StarGeneratorEvent.so" ); + gSystem->Load( "StarGeneratorBase.so" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "xgeometry.so" ); + + // Setup RNG seed and map all ROOT TRandom here + StarRandom::seed( rngSeed ); + StarRandom::capture(); + + // + // Create the primary event generator and insert it + // before the geant maker + // + // StarPrimaryMaker * + _primary = new StarPrimaryMaker(); + { + _primary -> SetFileName( "lambda_fwd_gun.root"); + chain -> AddBefore( "geant", _primary ); + } + + Kinematics(); + + // + // Initialize primary event generator and all sub makers + // + _primary -> Init(); + _primary->SetSigma( 0.1, 0.1, 0.1 ); // 1mm x 1mm x 1mm smearing at the vertex + _primary->SetVertex(0.0, 0.0, 0.0 ); + + // + // Setup geometry and set starsim to use agusread for input + // + //geometry("y2012"); + command("gkine -4 0"); + command("gfile o lambda_fwd_gun.fzd"); + + + hNumHits = new TH1F("hNumEvents","Nhits/plane/incident track vs event number",nevents + 1, -0.5, (float)( nevents ) + 0.5 ); + + // + // Trigger on nevents + // + trig( nevents ); + + TFile * f = new TFile( "lambda_gen.root", "RECREATE" ); + f->cd(); + hMll->Write(); + f->Write(); + + command("call agexit"); // Make sure that STARSIM exits properly + +} +// ---------------------------------------------------------------------------- + diff --git a/StRoot/StFwdTrackMaker/macro/sim/sim.C b/StRoot/StFwdTrackMaker/macro/sim/sim.C new file mode 100755 index 00000000000..beef7dfeb16 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/sim.C @@ -0,0 +1,242 @@ +//usr/bin/env root4star -l -b -q $0'("'${1:-sim.fzd}'",'${2:-2000}')'; exit $? +// that is a valid shebang to run script as executable, but with only one arg + + +// Run very fast fwd tracking +// generate some input data using genfzd + +TFile *output = 0; + +void sim( char *inFile = "sim.fzd", + int n = 100, // nEvents to run + bool useFstForSeedFinding = true, // use FTT (default) or FST for track finding + bool enableTrackRefit = true, // Enable track refit (default off) + bool realisticSim = true, // enables data-like mode, real track finding and fitting without MC seed + bool useZeroB = false + ) { + // report all of the parameters passed in + cout << "inFile = " << inFile << endl; + cout << "n = " << n << endl; + cout << "useFstForSeedFinding = " << useFstForSeedFinding << endl; + cout << "enableTrackRefit = " << enableTrackRefit << endl; + cout << "realisticSim = " << realisticSim << endl; + cout << "useZeroB = " << useZeroB << endl; + const char *geom = "y2024 agml usexgeom"; + TString _geom = geom; + + // Switches for common options + bool SiIneff = false; + bool useConstBz = false; + bool useFCS = true; + + // use cached + _geom = ""; + + // to use the geom cache (skip agml build which is faster) + // set the _geom string to "" and make sure the cache file ("fGeom.root") is present + // _geom = ""; + + // Setup the chain for reading an FZD + TString _chain; + if ( useFCS ) + _chain = Form("fzin %s sdt20211016 fstFastSim fcsSim fcsWFF fcsCluster fwdTrack MakeEvent StEvent McEvent ReverseField bigbig evout cmudst tree", _geom.Data() ); + else + _chain = Form("fzin %s sdt20211016 MakeEvent StEvent ReverseField bigbig fstFastSim fcsSim fwdTrack evout cmudst tree", _geom.Data()); + + gSystem->Load( "libStarRoot.so" ); + gROOT->SetMacroPath(".:/star-sw/StRoot/macros/:./StRoot/macros:./StRoot/macros/graphics:./StRoot/macros/analysis:./StRoot/macros/test:./StRoot/macros/examples:./StRoot/macros/html:./StRoot/macros/qa:./StRoot/macros/calib:./StRoot/macros/mudst:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/graphics:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/analysis:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/test:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/examples:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/html:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/qa:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/calib:/afs/rhic.bnl.gov/star/packages/DEV/StRoot/macros/mudst:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/macros:/afs/rhic.bnl.gov/star/ROOT/36/5.34.38/.sl73_x8664_gcc485/rootdeb/tutorials"); + gROOT->LoadMacro("bfc.C"); + bfc(-1, _chain, inFile); + + if ( useConstBz ) + StarMagField::setConstBz(true); + + gSystem->Load( "libStFttSimMaker" ); + gSystem->Load( "libStFcsTrackMatchMaker" ); + + gSystem->Load( "libMathMore.so" ); + gSystem->Load( "libStarGeneratorUtil" ); + + StFttFastSimMaker * fttSim = new StFttFastSimMaker(); + fttSim->SetDebug(); + chain->AddAfter("fcsSim", fttSim); + + // FCS setup, if included + if (useFCS) { + + StFcsDbMaker* fcsdbmkr = (StFcsDbMaker*) chain->GetMaker("fcsDbMkr"); + cout << "fcsdbmkr="<GetDataSet("fcsDb"); + fcsdb->forceFixGain(); + fcsdb->forceFixGainCorrection(); + cout << "fcsdb="<setDbAccess(1); + + // Configure FCS simulator + StFcsFastSimulatorMaker *fcssim = (StFcsFastSimulatorMaker*) chain->GetMaker("fcsSim"); + fcssim->setDebug(1); + //fcssim->setLeakyHcal(0); + + StFcsWaveformFitMaker *fcsWFF= (StFcsWaveformFitMaker*) chain->GetMaker("StFcsWaveformFitMaker"); + fcsWFF->setEnergySelect(0); + + StFcsClusterMaker *fcsclu = (StFcsClusterMaker*) chain->GetMaker("StFcsClusterMaker"); + fcsclu->setDebug(1); + } + + // { + gSystem->Load("StFwdUtils.so"); + // StFwdJPsiMaker *fwdJPsi = new StFwdJPsiMaker(); + // fwdJPsi->SetDebug(); + // chain->AddMaker(fwdJPsi); + // goto chain_loop; + // } + + + // Configure FST FastSim + TString qaoutname(gSystem->BaseName(inFile)); + qaoutname.ReplaceAll(".fzd", ".FastSimu.QA.root"); + StFstFastSimMaker *fstFastSim = (StFstFastSimMaker*) chain->GetMaker( "fstFastSim" );; + + if (SiIneff) + fstFastSim->SetInEfficiency(0.1); // inefficiency of Si + + fstFastSim->SetQAFileName(qaoutname); + + cout << "Adding StFstFastSimMaker to chain" << endl; + chain->AddAfter("fcsSim", fstFastSim); + + + // Configure the Forward Tracker + StFwdTrackMaker * fwdTrack = (StFwdTrackMaker*) chain->GetMaker( "fwdTrack" ); + + if ( fwdTrack ){ + fwdTrack->SetDebug(1); + // config file set here for ideal simulation + if (!realisticSim){ + cout << "Configured for ideal simulation (MC finding + MC mom seed)" << endl; + fwdTrack->setConfigForIdealSim( ); + } else { + cout << "Configured for realistic simulation" << endl; + fwdTrack->setConfigForRealisticSim( ); + cout << "Configured for realistic simulation DONE" << endl; + } + + if ( _geom == "" ){ + cout << "Using the Geometry cache: fGeom.root" << endl; + fwdTrack->setGeoCache( "fGeom.root" ); + } + + // choose + if (useFstForSeedFinding) + fwdTrack->setSeedFindingWithFst(); + else { // default for this true/false option + fwdTrack->setSeedFindingWithFtt(); + } + // other options + // fwdTrack->setSeedFindingWithFtt(); + // fwdTrack->setSeedFindingWithFstFttSequential(); + // fwdTrack->setSeedFindingWithFstFttSimultaneous(); + + fwdTrack->setTrackRefit( enableTrackRefit ); + fwdTrack->setConstB( useConstBz ); + fwdTrack->setOutputFilename( TString::Format( "%s.output.root", inFile ).Data() ); + fwdTrack->SetVisualize( false ); + fwdTrack->SetDebug(); + fwdTrack->setIncludePrimaryVertexInFit( false ); + + // fwdTrack->setTrackFittingOff(); + // fwdTrack->setUseMcSeedForFit(true); + // fwdTrack->setConfigKeyValue("") + if ( useZeroB ){ + cout << "Setting B = 0" << endl; + fwdTrack->setZeroB( true ); + } + bool doFitQA = true; + if ( doFitQA ){ + StFwdFitQAMaker *fwdFitQA = new StFwdFitQAMaker(); + fwdFitQA->SetDebug(); + TString fitqaoutname(gSystem->BaseName(inFile)); + fitqaoutname.ReplaceAll(".fzd", ".FwdFitQA.root"); + fwdFitQA->setOutputFilename( fitqaoutname ); + chain->AddAfter("fwdTrack", fwdFitQA); + } + cout << "fwd tracker setup" << endl; + } + + bool doFwdAna = true; + if (!useFCS && doFwdAna ){ + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(); + chain->AddAfter("fwdTrack", fwdAna); + } + + + StMuDstMaker * muDstMaker = (StMuDstMaker*)chain->GetMaker( "MuDst" ); + if (useFCS) { + // FwdTrack and FcsCluster assciation + gSystem->Load("StFcsTrackMatchMaker"); + StFcsTrackMatchMaker *match = new StFcsTrackMatchMaker(); + match->setMaxDistance(6,10); + match->setFileName("fcstrk.root"); + match->SetDebug(); + chain->AddMaker(match); + + if ( doFwdAna ){ + StFwdAnalysisMaker *fwdAna = new StFwdAnalysisMaker(); + fwdAna->SetDebug(); + chain->AddAfter("FcsTrkMatch", fwdAna); + } + + // Produce MuDst output + if ( muDstMaker ) + chain->AddAfter( "FcsTrkMatch", muDstMaker ); + } else { + if ( muDstMaker ) + chain->AddAfter( "fwdAna", muDstMaker ); + } + + if (muDstMaker){ + StFwdQAMaker *fwdQA = new StFwdQAMaker(); + fwdQA->SetDebug(2); + TString fwdqaname(gSystem->BaseName(inFile)); + fwdqaname.ReplaceAll(".fzd", ".FwdTree.root"); + fwdQA->setTreeFilename(fwdqaname); + chain->AddAfter("MuDst", fwdQA); + } + + // The PicoDst + gSystem->Load("libStPicoEvent"); + gSystem->Load("libStPicoDstMaker"); + StPicoDstMaker *picoMk = new StPicoDstMaker(StPicoDstMaker::IoWrite); + cout << "picoMk = " << picoMk << endl; + picoMk->setVtxMode(StPicoDstMaker::Default); + + +chain_loop: + chain->Init(); + + //_____________________________________________________________________________ + // + // MAIN EVENT LOOP + //_____________________________________________________________________________ + for (int i = 0; i < n; i++) { + + cout << "--------->START EVENT: " << i << endl; + + chain->Clear(); + if (kStOK != chain->Make()) + break; + + + // StMuDst * mds = muDstMaker->muDst(); + // StMuFwdTrackCollection * ftc = mds->muFwdTrackCollection(); + // cout << "Number of StMuFwdTracks: " << ftc->numberOfFwdTracks() << endl; + // for ( size_t iTrack = 0; iTrack < ftc->numberOfFwdTracks(); iTrack++ ){ + // StMuFwdTrack * muFwdTrack = ftc->getFwdTrack( iTrack ); + // cout << "muFwdTrack->mPt = " << muFwdTrack->momentum().Pt() << endl; + + // } + cout << "<---------- END EVENT" << endl; + } // event loop +} diff --git a/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C b/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C new file mode 100755 index 00000000000..ac8339cb399 --- /dev/null +++ b/StRoot/StFwdTrackMaker/macro/sim/single_particle_gun.C @@ -0,0 +1,28 @@ +//usr/bin/env root4star -l -b -q $0'('$1', '$2')'; exit $? +#include "gen.C" +#include "TString.h" + +void single_particle_gun( Int_t nevents=5000, Int_t rngSeed=541522, + TString particle="mu-", Int_t nParticles=1, + Float_t _minPt=0.1, Float_t _maxPt=1.0, + Float_t _minEta=2.5, Float_t _maxEta=4.0, + Float_t _minPhi=0.0, Float_t _maxPhi=2.0*TMath::Pi() + ) +{ + nameParticle = particle; + numParticles = nParticles; + minPt = _minPt; + maxPt = _maxPt; + minEta = _minEta; + maxEta = _maxEta; + minPhi = _minPhi; + maxPhi = _maxPhi; + + TString safeName = particle; + safeName.ReplaceAll("+", "plus"); + safeName.ReplaceAll("-", "minus"); + fzdFilename = TString::Format("single_particle_gun_%s_%dEvents_%dPerEvent_Pt_%0.2fto%0.2f_Eta_%0.2fto%0.2f_Phi_%0.2fto%0.2f.fzd", safeName.Data(), nevents, numParticles, minPt, maxPt, minEta, maxEta, minPhi, maxPhi); + primaryName = TString::Format("single_particle_gun_%s_%dEvents_%dPerEvent_Pt_%0.2fto%0.2f_Eta_%0.2fto%0.2f_Phi_%0.2fto%0.2f.root", safeName.Data(), nevents, numParticles, minPt, maxPt, minEta, maxEta, minPhi, maxPhi); + cout << "Writing output to: " << fzdFilename << endl; + gen( nevents, rngSeed ); +} diff --git a/StRoot/StFwdTrackMaker/macro/viz.C b/StRoot/StFwdTrackMaker/macro/viz.C old mode 100644 new mode 100755 index 2768834e087..db0d6e33f60 --- a/StRoot/StFwdTrackMaker/macro/viz.C +++ b/StRoot/StFwdTrackMaker/macro/viz.C @@ -1,9 +1,9 @@ +//usr/bin/env root -l -b -q $0'('$1')'; exit $? #include "TFile.h" #include "TH1F.h" #include "TH2F.h" #include "TTree.h" - TFile * fData; TTree * fwd; TH2 * hFrame; @@ -247,7 +247,7 @@ void viz_points(const char* name, const char* cmd, int color, int eventIndex, Pr //add function for seed finding-AGE void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType projType = kRZSigned){ - fwd->Draw( "reco.id", "", "goff", 1, eventIndex ); + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); int nTrks = fwd->GetSelectedRows(); TLine line; @@ -256,7 +256,7 @@ void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType TLine proj; for (int i = 0; i < nTrks; i++){ //loop over number of tracks - fwd->Draw( TString::Format("reco[%d].projs.mXYZ.fX:reco[%d].projs.mXYZ.fY:reco[%d].projs.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); + fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); auto nHits = fwd->GetSelectedRows(); auto projX = fwd->GetV1(); auto projY = fwd->GetV2(); @@ -290,7 +290,35 @@ void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType line.SetLineColor(1); }*/ - line.DrawLine(x0, y0, x1, y1); + +void viz_tracks(int nTrk, int eventIndex, ProjectionType projType, bool seeds = false, int iTrack = -1, bool filter = false){ + TLine ll; + ll.SetLineWidth(lineScale); + + // ll.DrawLine( 150, 10, 250, 20 ); + // Tracks + int NumTracksFound = 0; + for ( int i = 0; i < nTrk; i++ ){ + if ( iTrack >= 0 && i != iTrack ) continue; + + // fwd->Draw( TString::Format("reco[%d].projs.mXYZ.fX:reco[%d].projs.mXYZ.fY:reco[%d].projs.mXYZ.fZ", i, i, i), TString::Format("reco[%d].status>=1 && fabs(reco[%d].mChi2) > 0.5", i, i), "goff", 1, eventIndex ); + fwd->Draw( TString::Format("reco[%d].mProjections.mXYZ.fX:reco[%d].mProjections.mXYZ.fY:reco[%d].mProjections.mXYZ.fZ:reco[%d].mChi2:reco[%d].mDidFitConverge:reco[%d].mCharge", i, i, i, i, i, i), "", "goff", 1, eventIndex ); + // fwd->Draw( TString::Format("0:5:reco[%d].projs.mXYZ.fZ", i, i, i), "", "goff", 1, eventIndex ); + auto trkX = fwd->GetV1(); + auto trkY = fwd->GetV2(); + auto trkZ = fwd->GetV3(); + auto trkChi2 = fwd->GetV4(); + auto trkConv = fwd->GetVal(4); + auto trkQ = fwd->GetVal(5); + + TText text; + text.SetTextFont(43); + text.SetTextSize(36); + if (iTrack >= 0){ + text.DrawTextNDC( 0.05, 0.7, TString::Format( "chi2=%f", trkChi2[0] ) ); + text.DrawTextNDC( 0.05, 0.65, TString::Format( "converge=%d", trkConv[0] ) ); + }else { + // if ( trkChi2[0] > 100 ) continue; } } @@ -300,7 +328,7 @@ void viz_seed( const char* name, const char* cmd, int eventIndex, ProjectionType void viz_proj( int eventIndex, ProjectionType projType = kRZSigned, bool markers = false ){ //get number of tracks - fwd->Draw( "reco.id", "", "goff", 1, eventIndex); //check if this is correct data to use to get nTrks + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex); //check if this is correct data to use to get nTrks int nTrks = fwd->GetSelectedRows(); //create line for track @@ -351,26 +379,45 @@ void viz_proj( int eventIndex, ProjectionType projType = kRZSigned, bool markers } } } - if (markers){ - //add marker to the legend - TText *t = new TText(.5,.5,"Hello World !"); - t->SetTextColor(kBlack); - t->SetTextFont(43); - t->SetTextSize(20); - //make this more functional? - if ( projType == kRZSigned ){ - LegendY = 5; - } else if (projType == kXY ){ - LegendY = -15; - } - TMarker *mk1 = new TMarker( LegendX, LegendY, 23 ); - mk1->SetMarkerSize( 2.5 ); - mk1->SetMarkerColor( 2 ); - mk1->Draw("same"); - t->DrawText( LegendX + 2, LegendY - 0.5, TString::Format( "Projected Hits ") ); - } - -} //end of fn + + if (seeds == false) return; + + for ( int i = 0; i < nTrk; i++ ){ + if ( iTrack >= 0 && i != iTrack ) continue; + + fwd->Draw( TString::Format("reco[%d].seeds.pos.fX:reco[%d].seeds.pos.fY:reco[%d].seeds.pos.fZ", i, i, i), TString::Format("reco[%d].mDidFitConverge!=0", i), "goff", 1, eventIndex ); + auto seedX = fwd->GetV1(); + auto seedY = fwd->GetV2(); + auto seedZ = fwd->GetV3(); + + // printf( "Found %d seeds for track %d\n", fwd->GetSelectedRows(), i ); + // int slc = TColor::GetColorPalette(i*100 % 255); + ll.SetLineColor(kGreen); + + for ( int j = 0; j < fwd->GetSelectedRows()-1; j++ ){ + + float seedX1 = xx( seedX[j], seedY[j], seedZ[j], projType ); + float seedY1 = yy( seedX[j], seedY[j], seedZ[j], projType ); + + // printf( "seed(x=%f, y=%f, z=%)->(xx=%f, yy=%f)\n", seedX[j], seedY[j], seedZ[j], seedX1, seedY1 ); + + float seedX2 = xx( seedX[j+1], seedY[j+1], seedZ[j+1], projType ); + float seedY2 = yy( seedX[j+1], seedY[j+1], seedZ[j+1], projType ); + + // printf( "(%f, %f) -> (%f, %f)\n", seedX1, seedY1, seedX2, seedY2 ); + ll.DrawLine( seedX1, seedY1, seedX2, seedY2 ); + + TMarker *mk1 = new TMarker( seedX1, seedY1, 20 ); + mk1->SetMarkerSize( 2.5 ); + mk1->SetMarkerColor(kBlue); + mk1->Draw("same"); + + TMarker *mk2 = new TMarker( seedX2, seedY2, 20 ); + mk2->SetMarkerSize( 2.5 ); + mk2->SetMarkerColor(kBlue); + mk2->Draw("same"); + } // end loop j + } // end loop i //add function to compare lines @@ -395,7 +442,7 @@ void viz_stats( int eventIndex ){ fwd->Draw( "fcsX:fcsY:fcsZ", "", "goff", 1, eventIndex ); int numEpd = fwd->GetSelectedRows();*/ - fwd->Draw( "reco.id", "", "goff", 1, eventIndex ); + fwd->Draw( "reco.mChi2", "", "goff", 1, eventIndex ); int numTracks = fwd->GetSelectedRows(); fwd->Draw( "fst.pos.fX:fst.pos.fY:fst.pos.fZ", "", "goff", 1, eventIndex ); int numFst = fwd->GetSelectedRows(); @@ -422,12 +469,21 @@ void viz_stats( int eventIndex ){ text.DrawTextNDC( 0.05, statTextY, TString::Format("WCal Clusters : %d", numWcal) ); n(); text.DrawTextNDC( 0.05, statTextY, TString::Format("HCal Clusters : %d", numHcal) ); n(); - //print reco statistics - /*fwd->Draw( "reco.reco.projs.mXYZ:fX:reco.reco.projs.mXYZ:fY:reco.reco.projs.mXYZ:fZ", "", "goff", 1, eventIndex ); - int numReco = fwd->GetSelectedRows(); - statTextY = 0.92; - text.DrawTextNDC( 0.35, statTextY, TString::Format("Reco Hits : %d", numReco) ); n();*/ + fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, eventIndex ); + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Tracks : %d", fwd->GetSelectedRows()) ); n(); + + fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100", "goff", 1, eventIndex ); + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); + + fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100 && reco.mCharge==1", "goff", 1, eventIndex ); + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Pos Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); + fwd->Draw( "reco.mPrimaryMomentum.fX", "reco.mChi2<100 && reco.mCharge==-1", "goff", 1, eventIndex ); + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Neg Tracks (good) : %d", fwd->GetSelectedRows()) ); n(); + // fwd->Draw( "seeds.trackId", "", "goff", 1, eventIndex ); + // fwd->Draw( "nSeedTracks", "", "goff", 1, eventIndex ); + // mTotalSeeds = fwd->GetV1()[0]; + text.DrawTextNDC( 0.05, statTextY, TString::Format("#Seeds : %d", mTotalSeeds ) ); n(); } @@ -452,15 +508,17 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ printf( "Visualizing Event %d \n", eventIndex ); - fwd->Draw( "reco.id", "", "", 1, eventIndex ); - int nTrk = fwd->GetSelectedRows(); //number of reco tracks - printf( "Event has %d Tracks \n", nTrk ); //changed from %lld to %d to eliminate an error that occurred-AGE + fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, eventIndex ); + int nTrk = fwd->GetSelectedRows(); + printf( "Event has %lld Tracks \n", nTrk ); hFrame->Draw("colz"); - //add detector locations - if (projType == kRZSigned){ + viz_points( "FTT", "fttPoints.mXYZ.fX:fttPoints.mXYZ.fY:fttPoints.mXYZ.fZ", kRed, eventIndex, projType ); + // viz_points( "FTC", "fttClusters.pos.fX:fttClusters.pos.fY:-fttClusters.pos.fZ", kGreen, eventIndex, projType, "fttClusters.mNStrips>2" ); + viz_points( "FST", "fstHits.mXYZ.fX:fstHits.mXYZ.fY:fstHits.mXYZ.fZ", kRed, eventIndex, projType ); + viz_points( "FCS", "wcalClusters.mXYZ.fX:wcalClusters.mXYZ.Y():wcalClusters.mXYZ.Z():wcalClusters.mClu.mEnergy", kGray, eventIndex, projType ); TLine *fst1 = new TLine(151.75, -28.3, 151.75, 28.3); fst1->SetLineWidth(2); @@ -475,22 +533,9 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ fst3->SetLineColor(12); fst3->Draw("same"); - TLine *ftt1 = new TLine(281, -60, 281, 60); - ftt1->SetLineWidth(2); - ftt1->SetLineColor(12); - ftt1->Draw("same"); - TLine *ftt2 = new TLine(304, -60, 304, 60); - ftt2->SetLineWidth(2); - ftt2->SetLineColor(12); - ftt2->Draw("same"); - TLine *ftt3 = new TLine(325, -60, 325, 60); - ftt3->SetLineWidth(2); - ftt3->SetLineColor(12); - ftt3->Draw("same"); - TLine *ftt4 = new TLine(348, -60, 348, 60); - ftt4->SetLineWidth(2); - ftt4->SetLineColor(12); - ftt4->Draw("same"); + + viz_tracks(nTrk, eventIndex, projType, false); + //viz_seeds(nTrk, eventIndex, projType); TLine *epd = new TLine(375, -130, 375, 130); epd->SetLineWidth(2); @@ -510,15 +555,15 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ //viz_points( "FST", "fstX:fstY:fstZ", kGray, eventIndex, projType/*, true*/ ); //viz_points( "EPD", "epdX:epdY:epdZ:epdE", kBlue, eventIndex, projType/*, true*/ ); //epd hits (only in fwdtree2)-AGE //viz_points( "FCS", "fcsX:fcsY:fcsZ:fcsE", kGreen, eventIndex, projType/*, true*/ ); - viz_points( "FST", "fst.pos.fX:fst.pos.fY:fst.pos.fZ", kGray, eventIndex, projType, true ); - viz_points( "FTT", "ftt.pos.fX:ftt.pos.fY:ftt.pos.fZ", kRed, eventIndex, projType ); - viz_points( "FTT Clusters", "fttClusters.pos.fX:fttClusters.pos.fY:fttClusters.pos.fZ", kRed, eventIndex, projType ); - viz_points( "WCal Hits", "wcalHits.starXYZ.fX:wcalHits.starXYZ.fY:wcalHits.starXYZ.fZ+705:100*wcalHits.energy", kBlue, eventIndex, projType ); - viz_points( "HCal Hits", "hcalHits.starXYZ.fX:hcalHits.starXYZ.fY:hcalHits.starXYZ.fZ+785:100*wcalClusters.mEnergy", kTeal, eventIndex, projType/*, true*/ ); - viz_points( "WCal Clusters", "wcalClusters.pos.fX:wcalClusters.pos.fY:wcalClusters.pos.fZ+705:100*wcalClusters.mEnergy", kViolet, eventIndex, projType/*, true*/ ); - viz_points( "HCal Clusters", "hcalClusters.pos.fX:hcalClusters.pos.fY:hcalClusters.pos.fZ+785:100*wcalClusters.mEnergy", kGreen, eventIndex, projType/*, true*/ ); //add fcs hits-AGE - - viz_seed( "Seeds", "seeds.pos.fX:seeds.pos.fY:seeds.pos.fZ", eventIndex, projType ); + viz_points( "FST", "fst.mXYZ.fX:fst.mXYZ.fY:fst.mXYZ.fZ", kGray, eventIndex, projType, true ); + viz_points( "FTT", "ftt.mXYZ.fX:ftt.mXYZ.fY:ftt.mXYZ.fZ", kRed, eventIndex, projType ); + // viz_points( "FTT Clusters", "fttClusters.pos.fX:fttClusters.pos.fY:fttClusters.pos.fZ", kRed, eventIndex, projType ); + // viz_points( "WCal Hits", "wcalHits.starXYZ.fX:wcalHits.starXYZ.fY:wcalHits.starXYZ.fZ+705:100*wcalHits.energy", kBlue, eventIndex, projType ); + // viz_points( "HCal Hits", "hcalHits.starXYZ.fX:hcalHits.starXYZ.fY:hcalHits.starXYZ.fZ+785:100*wcalClusters.mEnergy", kTeal, eventIndex, projType/*, true*/ ); + // viz_points( "WCal Clusters", "wcalClusters.pos.fX:wcalClusters.pos.fY:wcalClusters.pos.fZ+705:100*wcalClusters.mEnergy", kViolet, eventIndex, projType/*, true*/ ); + // viz_points( "HCal Clusters", "hcalClusters.pos.fX:hcalClusters.pos.fY:hcalClusters.pos.fZ+785:100*wcalClusters.mEnergy", kGreen, eventIndex, projType/*, true*/ ); //add fcs hits-AGE + + // viz_seed( "Se-=[eds", "seeds.pos.fX:seeds.pos.fY:seeds.pos.fZ", eventIndex, projType ); //viz_proj( eventIndex, projType, false); //viz_points( "Proj", "reco.reco.projs.mXYZ.fX:reco.reco.projs.mXYZ.fY:reco.reco.projs.mXYZ.fZ", kRed, eventIndex, projType); return nTrk; @@ -526,9 +571,10 @@ int viz_event( int eventIndex, ProjectionType projType = kRZSigned ){ //change to name of file being used-AGE -void viz( TString fn = "fwdtree5.root", int view = kXY) { +void viz( int maxEvents = 10, TString fn = "fwdtree.root", int view = kXY) { + +void viz( int mode = 0, int maxEvents = 10, TString fn = "fwdtree.root") { - ProjectionType pjt = (ProjectionType)view; fData = new TFile( fn ); fwd = (TTree*)fData->Get( "fwd" ); @@ -561,6 +607,7 @@ void viz( TString fn = "fwdtree5.root", int view = kXY) { // gPad->SetMargin(0.1, 0.05, 0.15, 0.05); int nEvents = fwd->GetEntries(); + if (nEvents > maxEvents) nEvents = maxEvents; // nEvents = 1; for ( int iEvent = 0; iEvent < nEvents; iEvent ++ ){ @@ -581,7 +628,7 @@ void viz( TString fn = "fwdtree5.root", int view = kXY) { padStat->cd(); padStat->Clear(); - viz_stats( iEvent ); //changed to provide number of tracks as well-AGE + // viz_stats( iEvent ); //changed to provide number of tracks as well-AGE padStat->Update(); gCan->Update(); gCan->Print( TString::Format( "out_event%d.pdf", iEvent ) ); @@ -595,4 +642,37 @@ void viz( TString fn = "fwdtree5.root", int view = kXY) { hFrame->Reset(); } -} \ No newline at end of file + if ( mode != 1 ) return; + // visualize the event one track at a time + for ( int inEvent = 0; inEvent < nEvents; inEvent++ ){ + fwd->Draw( "reco.mPrimaryMomentum.fX", "", "goff", 1, inEvent ); + int nTrk = fwd->GetSelectedRows(); + printf( "Event %d has %lld Tracks \n", inEvent, nTrk ); + + for ( int iTrack = 0; iTrack < nTrk; iTrack ++ ){ + + printf( "Track: %d\n", iTrack ); + + padRZ->cd(); + // int nTrk = viz_event( iEvent, kRZSigned ); + viz_event( inEvent, kRZSigned, true ); + viz_tracks(nTrk, inEvent, kRZSigned, true, iTrack); + padXY->cd(); + viz_event( inEvent, kXY, true ); + viz_tracks(nTrk, inEvent, kXY, true, iTrack); + if (nTrk > -1){ + padRZ->Update(); + padXY->Update(); + + padStat->cd(); + padStat->Clear(); + // viz_stats( iEvent ); + padStat->Update(); + gCan->Update(); + gCan->Print( TString::Format( "out_event%d_track%d.pdf", inEvent, iTrack ) ); + } + hFrame->Reset(); + } + } + +} From 6dbc564c30d7f7369db64b897a078b272d91eef9 Mon Sep 17 00:00:00 2001 From: Daniel Brandenburg Date: Thu, 30 Jan 2025 12:25:14 -0500 Subject: [PATCH 09/10] add log statements to better identify seg fault location --- StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx index 4e1d6d39fa4..eac860bef41 100644 --- a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx +++ b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx @@ -230,7 +230,7 @@ int StFwdTrackMaker::Finish() { void StFwdTrackMaker::LoadConfiguration() { if (mConfigFile.length() < 5){ - LOG_INFO << "Forward Tracker is using default config for "; + LOG_INFO << "WOAH: Forward Tracker is using default config for "; if ( defaultConfig == defaultConfigData ){ LOG_INFO << " DATA" << endm; } else { @@ -246,7 +246,9 @@ void StFwdTrackMaker::LoadConfiguration() { //________________________________________________________________________ int StFwdTrackMaker::Init() { + LOG_INFO << "StFwdTrackMaker::Init()" << endm; if ( !configLoaded ){ + defaultConfig = defaultConfigData; LoadConfiguration(); } @@ -1073,6 +1075,7 @@ TVector3 StFwdTrackMaker::GetEventPrimaryVertex(){ //________________________________________________________________________ int StFwdTrackMaker::Make() { + LOG_INFO << ">>StFwdTrackMaker::Make" << endm; // START time for measuring tracking long long itStart = FwdTrackerUtils::nowNanoSecond(); @@ -1089,7 +1092,7 @@ int StFwdTrackMaker::Make() { // get the primary vertex for use with FWD tracking mFwdVertexSource = StFwdTrackMaker::kFwdVertexSourceUnknown; GetEventPrimaryVertex(); - LOG_DEBUG << "FWD Vertex Source: " << mFwdVertexSource << endm; + LOG_INFO << "FWD Vertex Source: " << mFwdVertexSource << endm; if ( mFwdVertexSource == kFwdVertexSourceNone ){ // TODO: add clean support for beamline constraints setIncludePrimaryVertexInFit( false ); @@ -1114,13 +1117,14 @@ int StFwdTrackMaker::Make() { /**********************************************************************/ // Load sTGC - LOG_DEBUG << ">>StFwdTrackMaker::loadFttHits" << endm; + LOG_INFO << ">>StFwdTrackMaker::loadFttHits" << endm; if ( IAttr("useFtt") ) { loadFttHits( mcTrackMap, hitMap ); } /**********************************************************************/ // Load FST + LOG_INFO << ">>StFwdTrackMaker::loadFstHits" << endm; if ( IAttr("useFst") ) { LOG_DEBUG << ">>StFwdTrackMaker::loadFstHits" << endm; int fstCount = loadFstHits( mcTrackMap, fsiHitMap ); From 39e63ee3564fb6b068f6b5d81847851849c67b22 Mon Sep 17 00:00:00 2001 From: Daniel Brandenburg Date: Thu, 30 Jan 2025 16:40:00 -0500 Subject: [PATCH 10/10] do not search for event vertex --- StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx index eac860bef41..9d3d26f7604 100644 --- a/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx +++ b/StRoot/StFwdTrackMaker/StFwdTrackMaker.cxx @@ -1084,14 +1084,16 @@ int StFwdTrackMaker::Make() { /**********************************************************************/ // Access forward track and hit maps + LOG_INFO << ">>StFwdTrackMaker::Make: Accessing FWD Data" << endm; FwdDataSource::McTrackMap_t &mcTrackMap = mForwardData->getMcTracks(); FwdDataSource::HitMap_t &hitMap = mForwardData->getFttHits(); FwdDataSource::HitMap_t &fsiHitMap = mForwardData->getFstHits(); /**********************************************************************/ // get the primary vertex for use with FWD tracking + LOG_INFO << ">>StFwdTrackMaker::GetEventPrimaryVertex info" << endm; mFwdVertexSource = StFwdTrackMaker::kFwdVertexSourceUnknown; - GetEventPrimaryVertex(); + // GetEventPrimaryVertex(); LOG_INFO << "FWD Vertex Source: " << mFwdVertexSource << endm; if ( mFwdVertexSource == kFwdVertexSourceNone ){ // TODO: add clean support for beamline constraints