File indexing completed on 2026-08-31 08:21:23
0001
0002
0003 #ifndef TPCTRACKRECO_TPCPOLYCLUSTERIZER_H
0004 #define TPCTRACKRECO_TPCPOLYCLUSTERIZER_H
0005
0006 #include <fun4all/SubsysReco.h>
0007 #include <trackbase/TrkrDefs.h>
0008
0009 #include <array>
0010 #include <string>
0011 #include <vector>
0012
0013 class Tpc_AssembledTrackContainer;
0014 class IdealPadMap;
0015 class PHCompositeNode;
0016 class PHGarfield;
0017 class Tpc_PolyClusterContainer;
0018 class TpcCrossingDecisionContainer;
0019 class TrkrHitSetContainer;
0020 class PHG4CylinderGeomContainer;
0021 class PHG4TpcGeomContainer;
0022
0023 class Tpc_PolyClusterizer : public SubsysReco
0024 {
0025 public:
0026 explicit Tpc_PolyClusterizer(const std::string& name = "Tpc_PolyClusterizer");
0027 ~Tpc_PolyClusterizer() override;
0028
0029 int InitRun(PHCompositeNode*) override;
0030 int process_event(PHCompositeNode*) override;
0031
0032 static constexpr unsigned int NPhiSamples = 3;
0033
0034 void setInputNodeName(const std::string& n) { m_inputNodeName = n; }
0035 void setOutputNodeName(const std::string& n) { m_outputNodeName = n; }
0036 void setCrossingDecisionNodeName(const std::string& n) { m_crossingDecisionNodeName = n; }
0037 void setMaxAcceptedTier(unsigned char v) { m_maxAcceptedTier = v; }
0038 void setT0(double v) { m_t0 = v; }
0039 void setTpcAdcClock(double v) { m_tpcAdcClock = v; }
0040 void setCrossingPeriodNs(double v) { m_crossingPeriodNs = v; }
0041 void setReverseDriftStepNs(double v) { m_reverseDriftStepNs = v; }
0042 void setKEffSide0(double v) { m_kEffSide0 = v; }
0043 void setKEffSide1(double v) { m_kEffSide1 = v; }
0044 void setCMVoltageDefault(double v) { m_cmVoltageDefault = v; }
0045 void setUseSurveyGeometry(bool v) { use_survey_geometry = v; }
0046 void setMoveTpc(double x, double y, double z) { m_tpcMove = {{x, y, z}}; }
0047 void setRotateTpc(unsigned int index, double x, double y, double z)
0048 {
0049 if (index < m_tpcRotations.size()) m_tpcRotations[index] = {{x, y, z}};
0050 }
0051 void setStartZ(double south_z, double north_z)
0052 {
0053 m_startZSouth = south_z;
0054 m_startZNorth = north_z;
0055 }
0056
0057 private:
0058 struct Point
0059 {
0060 TrkrDefs::hitsetkey hitsetkey{0};
0061 TrkrDefs::hitkey hitkey{0};
0062 unsigned int layer{0};
0063 unsigned int side{0};
0064 unsigned int pad{0};
0065 unsigned int tbin{0};
0066 double adc{0.0};
0067 double x{0.0};
0068 double y{0.0};
0069 double z{0.0};
0070 };
0071
0072 struct Centroid
0073 {
0074 bool ok{false};
0075 unsigned int layer{0};
0076 double x{0.0};
0077 double y{0.0};
0078 double z{0.0};
0079 double rms_x{0.0};
0080 double rms_y{0.0};
0081 double rms_z{0.0};
0082 };
0083
0084 struct ClusterParameters
0085 {
0086 double adc{0.0};
0087 unsigned int phi_width{0};
0088 unsigned int time_width{0};
0089 double phase{0.0};
0090 };
0091
0092 struct DriftPoint
0093 {
0094 float delta_r{0.0F};
0095 float delta_phi{0.0F};
0096 float z{0.0F};
0097 };
0098
0099 struct DriftPolyline
0100 {
0101 double phi{0.0};
0102 std::vector<DriftPoint> points;
0103 };
0104
0105 int getNodes(PHCompositeNode*);
0106 int createNodes(PHCompositeNode*);
0107 bool make_xyz_point(TrkrDefs::hitsetkey hsk, TrkrDefs::hitkey hk, short crossing, Point& p) const;
0108 bool build_drift_lookup();
0109 bool sample_drift_lookup(unsigned int layer,
0110 unsigned int side,
0111 unsigned int pad,
0112 unsigned int tbin,
0113 short crossing,
0114 double& x,
0115 double& y,
0116 double& z) const;
0117 ClusterParameters make_cluster_parameters(const std::vector<Point>& points, const Centroid& centroid, int side) const;
0118 static Centroid make_centroid(const std::vector<Point>& points);
0119 void configure_garfield(PHGarfield* garfield) const;
0120 static unsigned int drift_lookup_index(unsigned int layer_index, unsigned int side, unsigned int sector, unsigned int sample);
0121 std::string m_inputNodeName;
0122 std::string m_outputNodeName;
0123 std::string m_crossingDecisionNodeName{"TPC_CROSSING_DECISIONS"};
0124 unsigned char m_maxAcceptedTier{1};
0125 Tpc_AssembledTrackContainer* m_assembledTracks{nullptr};
0126 Tpc_PolyClusterContainer* m_clusters{nullptr};
0127 TpcCrossingDecisionContainer* m_crossingDecisions {nullptr};
0128 TrkrHitSetContainer* m_hits{nullptr};
0129 IdealPadMap* m_idealPadMap{nullptr};
0130 PHGarfield* m_garfield{nullptr};
0131 PHG4TpcGeomContainer* m_geomContainerTpc{nullptr};
0132 std::array<DriftPolyline, 48 * 2 * 12 * NPhiSamples> m_driftLookup;
0133 unsigned int m_event{0};
0134 double m_t0{8};
0135 double m_tpcAdcClock{56.881262};
0136 double m_crossingPeriodNs {106.56};
0137 double m_reverseDriftStepNs{56.881262};
0138 double m_startZSouth{-102.325};
0139 double m_startZNorth{102.325};
0140 double m_kEffSide0{0.0};
0141 double m_kEffSide1{-1.5};
0142 double m_cmVoltageDefault{380.0};
0143 bool use_survey_geometry = false;
0144 std::array<double, 3> m_tpcMove{{0.0, 0.0, 0.0}};
0145 std::array<std::array<double, 3>, 2> m_tpcRotations{{{{0.0, 0.0, 0.0}}, {{0.0, 0.0, 0.0}}}};
0146 };
0147 #endif