Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2026-08-31 08:21:44

0001 // Tell emacs that this is a C++ source
0002 // -*- C++ -*-.
0003 #ifndef TRACKINGDIAGNOSTICS_TPCV0CANDIDATETREE_H
0004 #define TRACKINGDIAGNOSTICS_TPCV0CANDIDATETREE_H
0005 
0006 #include <tpctrackreco/TpcTrackFit.h>
0007 
0008 #include <fun4all/SubsysReco.h>
0009 
0010 #include <cstdint>
0011 #include <map>
0012 #include <string>
0013 #include <vector>
0014 
0015 class PHCompositeNode;
0016 class PHField;
0017 class PHG4Hit;
0018 class PHG4HitContainer;
0019 class PHG4TruthInfoContainer;
0020 class TFile;
0021 class TTree;
0022 class Tpc_PolyClusterContainer;
0023 class Tpc_PolyTrackContainer;
0024 class Tpc_PolyTrackVertexContainer;
0025 
0026 class TpcV0CandidateTree : public SubsysReco
0027 {
0028  public:
0029   TpcV0CandidateTree(const std::string &name = "TpcV0CandidateTree",
0030                      const std::string &filename = "TpcV0Candidates.root");
0031   ~TpcV0CandidateTree() override = default;
0032 
0033   int Init(PHCompositeNode *topNode) override;
0034   int process_event(PHCompositeNode *topNode) override;
0035   int End(PHCompositeNode *topNode) override;
0036 
0037   void set_output_file(const std::string &filename) { m_filename = filename; }
0038   void set_truth_point_node(const std::string &name) { m_truth_point_node = name; }
0039   void set_truth_info_node(const std::string &name) { m_truth_info_node = name; }
0040   void set_tpc_sa_cluster_node(const std::string &name) { m_tpc_sa_cluster_node = name; }
0041   void set_tpc_sa_track_node(const std::string &name) { m_tpc_sa_track_node = name; }
0042   void set_tpc_sa_track_vertex_node(const std::string &name) { m_tpc_sa_track_vertex_node = name; }
0043   void use_pattern_cluster_tracks(const bool value = true) { m_use_pattern_cluster_tracks = value; }
0044   void set_use_truth_primary_vertex(const bool value) { m_use_truth_primary_vertex = value; }
0045   void set_primary_vertex(const double x, const double y, const double z);
0046 
0047   void set_min_points(const int value) { m_min_points = value; }
0048   void set_fit_helix(const bool value)
0049   {
0050     m_fit_helix_tracks = value;
0051     if (value)
0052     {
0053       m_fit_kalman_tracks = false;
0054     }
0055   }
0056   void set_fit_kalman(const bool value)
0057   {
0058     m_fit_kalman_tracks = value;
0059     if (value)
0060     {
0061       m_fit_helix_tracks = false;
0062       m_use_final_track_helix = false;
0063     }
0064   }
0065   bool set_track_fit_method(const std::string &mode);
0066   void set_use_final_track_helix(const bool value) { m_use_final_track_helix = value; }
0067   bool set_point_order(const std::string &mode);
0068   void set_fit_first_points(const int value) { m_fit_first_points = value; }
0069   void set_bfield(const double value)
0070   {
0071     m_bfield_t = value;
0072     m_kalman_config.bfield_t = value;
0073   }
0074   void set_kalman_magnetic_field(const PHField *field) { m_kalman_config.magnetic_field = field; }
0075   void set_kalman_analytic_uniform_propagation(const bool value = true)
0076   {
0077     m_kalman_config.analytic_uniform_propagation = value;
0078   }
0079   void use_kalman_field_map(const bool value = true)
0080   {
0081     m_use_kalman_field_map = value;
0082     if (!value)
0083     {
0084       m_kalman_config.magnetic_field = nullptr;
0085     }
0086   }
0087   void set_kalman_rkn4(const double max_step_cm,
0088                        const double step_tolerance,
0089                        const int max_step_trials = 12,
0090                        const int max_total_steps = 2000)
0091   {
0092     m_kalman_config.rkn_max_step_cm = max_step_cm;
0093     m_kalman_config.rkn_step_tolerance = step_tolerance;
0094     m_kalman_config.rkn_max_step_trials = max_step_trials;
0095     m_kalman_config.rkn_max_total_steps = max_total_steps;
0096   }
0097   void set_kalman_fast_field_jacobian(const bool value = true)
0098   {
0099     m_kalman_config.rkn_fast_field_jacobian = value;
0100   }
0101   void set_kalman_fast_field_pca(const bool value = true)
0102   {
0103     m_kalman_config.rkn_fast_field_pca = value;
0104   }
0105   void set_kalman_field_pca_refine_iterations(const int value)
0106   {
0107     m_kalman_config.rkn_field_pca_refine_iterations = value;
0108   }
0109   void set_theta_extension(const double value) { m_theta_extension = value; }
0110   void set_coarse_steps(const int value) { m_coarse_steps = value; }
0111   void set_pca_candidates(const int value) { m_pca_candidates = value; }
0112   void set_print_timing(const bool value = true) { m_print_timing = value; }
0113   void set_downstream_margin(const double value) { m_downstream_margin = value; }
0114   void set_final_track_helix_search(const double max_upstream_cm,
0115                                     const double downstream_margin_cm)
0116   {
0117     m_final_track_helix_max_upstream_cm = max_upstream_cm;
0118     m_final_track_helix_downstream_margin_cm = downstream_margin_cm;
0119   }
0120   void set_kalman_search(const double max_upstream_cm, const double downstream_margin_cm)
0121   {
0122     m_kalman_max_upstream_cm = max_upstream_cm;
0123     m_kalman_downstream_margin_cm = downstream_margin_cm;
0124   }
0125   void set_kalman_measurement_sigmas(const double xy_cm, const double z_cm)
0126   {
0127     set_kalman_measurement_sigmas(xy_cm, xy_cm, z_cm);
0128   }
0129   void set_kalman_measurement_sigmas(const double rphi_cm,
0130                                      const double r_cm,
0131                                      const double z_cm)
0132   {
0133     m_kalman_config.meas_sigma_rphi_cm = rphi_cm;
0134     m_kalman_config.meas_sigma_r_cm = r_cm;
0135     m_kalman_config.meas_sigma_z_cm = z_cm;
0136   }
0137   void set_write_kalman_innovation_diagnostics(const bool value = true)
0138   {
0139     m_kalman_config.collect_innovation_components = value;
0140   }
0141   void set_kalman_process_sigmas(const double pos_cm,
0142                                  const double phi,
0143                                  const double qop_t,
0144                                  const double tanl)
0145   {
0146     m_kalman_config.process_sigma_pos_cm = pos_cm;
0147     m_kalman_config.process_sigma_phi = phi;
0148     m_kalman_config.process_sigma_qop_t = qop_t;
0149     m_kalman_config.process_sigma_tanl = tanl;
0150   }
0151   void set_kalman_material(const double x0_per_cm,
0152                            const double multiple_scattering_scale,
0153                            const double energy_loss_gev_per_cm,
0154                            const double energy_loss_sigma_fraction)
0155   {
0156     m_kalman_config.material_x0_per_cm = x0_per_cm;
0157     m_kalman_config.multiple_scattering_scale = multiple_scattering_scale;
0158     m_kalman_config.energy_loss_gev_per_cm = energy_loss_gev_per_cm;
0159     m_kalman_config.energy_loss_sigma_fraction = energy_loss_sigma_fraction;
0160   }
0161   void set_prefer_positive_pointing(const bool value) { m_prefer_positive_pointing = value; }
0162 
0163   void set_pre_track_pt_min(const double value) { m_pre_track_pt_min = value; }
0164   void set_pre_track_dca_xy_min(const double value) { m_pre_track_dca_xy_min = value; }
0165   void set_pre_track_dca_z_min(const double value) { m_pre_track_dca_z_min = value; }
0166   void set_pre_track_dca_xy_max(const double value) { m_pre_track_dca_xy_max = value; }
0167   void set_pre_track_dca_z_max(const double value) { m_pre_track_dca_z_max = value; }
0168   void set_pre_pair_dca_max(const double value) { m_pre_pair_dca_max = value; }
0169   void set_pre_lproj_min(const double value) { m_pre_lproj_min = value; }
0170   void set_pre_cos_theta_min(const double value) { m_pre_cos_theta_min = value; }
0171   void set_pre_track_quality_max(const double value) { m_pre_track_quality_max = value; }
0172   void set_pre_track_npoints_min(const int value) { m_pre_track_npoints_min = value; }
0173   void set_pair_pca_z_max(const double value) { m_pair_pca_z_max = value; }
0174   void set_pair_pca_dz_max(const double value) { m_pair_pca_dz_max = value; }
0175   void set_pair_decay_radius_min(const double value) { m_pair_decay_radius_min = value; }
0176   void set_pair_alpha_abs_max(const double value) { m_pair_alpha_abs_max = value; }
0177   void set_pair_dca_max(const double value) { m_pair_dca_max = value; }
0178   void set_pair_dira_min(const double value) { m_pair_dira_min = value; }
0179   void set_write_same_sign_pairs(const bool value) { m_write_same_sign_pairs = value; }
0180   void set_write_cluster_residual_tree(const bool value) { m_write_cluster_residual_tree = value; }
0181 
0182  private:
0183   using Vec3 = TpcTrackVec3;
0184   using TruthPoint = TpcTrackPoint;
0185   using HelixFit = TpcTrackHelix;
0186   using HelixPca = TpcTrackHelixPca;
0187   using HelixSearchRange = TpcTrackHelixSearchRange;
0188   using LinePca = TpcTrackLinePca;
0189   using PointOrder = TpcTrackPointOrder;
0190 
0191   struct Tracklet
0192   {
0193     int track_id{0};
0194     int shower_id{0};
0195     int pid{0};
0196     int parent_id{0};
0197     int parent_pid{0};
0198     int primary_id{0};
0199     int vtx_id{0};
0200     int barcode{0};
0201     int embed_id{0};
0202     int is_primary{0};
0203     int charge{0};
0204     int side{-1};
0205     int npoints{0};
0206     unsigned int ntpc_clusters{0};
0207     bool has_dedx{false};
0208     double dedx{0.0};
0209     Vec3 position;
0210     Vec3 momentum;
0211     Vec3 truth_momentum;
0212     double truth_e{0.0};
0213     Vec3 truth_vertex;
0214     double truth_vt{0.0};
0215     std::vector<TruthPoint> points;
0216     bool has_helix{false};
0217     HelixFit helix;
0218     bool has_helix_search_range{false};
0219     HelixSearchRange helix_search_range;
0220     bool has_kalman{false};
0221     TpcKalmanResult kalman;
0222     double fit_chi2{0.0};
0223     int fit_ndf{0};
0224     double fit_chi2_ndf{0.0};
0225     bool has_vertex_dca{false};
0226     std::pair<double, double> vertex_dca;
0227     bool has_beamline_pca{false};
0228     Vec3 beamline_pca;
0229     double rdca_zero{0.0};
0230     bool has_pattern_vertex{false};
0231     Vec3 pattern_vertex;
0232     double pattern_vertex_z_rms{0.0};
0233     unsigned int pattern_vertex_ntracks{0};
0234   };
0235 
0236   struct KalmanPca
0237   {
0238     Vec3 pca1;
0239     Vec3 pca2;
0240     double dca{0.0};
0241     double s1{0.0};
0242     double s2{0.0};
0243   };
0244 
0245   struct PairRow
0246   {
0247     int run{0};
0248     int evt{0};
0249     short cross1{0};
0250     short cross2{0};
0251 
0252     float px1{0.0F};
0253     float py1{0.0F};
0254     float pz1{0.0F};
0255     float px2{0.0F};
0256     float py2{0.0F};
0257     float pz2{0.0F};
0258 
0259     float dca_xy1{0.0F};
0260     float dca_z1{0.0F};
0261     float dca_xy2{0.0F};
0262     float dca_z2{0.0F};
0263     float pairDCA{0.0F};
0264 
0265     float alpha{0.0F};
0266     float qT{0.0F};
0267     float charge1{0.0F};
0268     float charge2{0.0F};
0269     float dedx_1{0.0F};
0270     float dedx_2{0.0F};
0271     float cosThetaReco{0.0F};
0272     float Lproj{0.0F};
0273 
0274     float pca_x{0.0F};
0275     float pca_y{0.0F};
0276     float pca_z{0.0F};
0277     float pca1_x{0.0F};
0278     float pca1_y{0.0F};
0279     float pca1_z{0.0F};
0280     float pca2_x{0.0F};
0281     float pca2_y{0.0F};
0282     float pca2_z{0.0F};
0283 
0284     float v0_px{0.0F};
0285     float v0_py{0.0F};
0286     float v0_pz{0.0F};
0287     float v0_pt{0.0F};
0288     float mass_Kshort{0.0F};
0289     float mass_Lambda{0.0F};
0290     float mass_AntiLambda{0.0F};
0291 
0292     float true_decay_x{0.0F};
0293     float true_decay_y{0.0F};
0294     float true_decay_z{0.0F};
0295     float pca_to_true_3d{0.0F};
0296     float pca_to_true_xy{0.0F};
0297     float pca_to_true_z{0.0F};
0298     float truth_alpha{0.0F};
0299     float truth_qT{0.0F};
0300     float delta_alpha{0.0F};
0301     float delta_qT{0.0F};
0302     float truth_px1{0.0F};
0303     float truth_py1{0.0F};
0304     float truth_pz1{0.0F};
0305     float truth_px2{0.0F};
0306     float truth_py2{0.0F};
0307     float truth_pz2{0.0F};
0308     float cos_mom1_truth{0.0F};
0309     float cos_mom2_truth{0.0F};
0310     float pca_theta1{0.0F};
0311     float pca_theta2{0.0F};
0312     float kalman_chi2_1{0.0F};
0313     float kalman_chi2_2{0.0F};
0314     float kalman_chi2_ndf1{0.0F};
0315     float kalman_chi2_ndf2{0.0F};
0316     float quality1{0.0F};
0317     float quality2{0.0F};
0318 
0319     int track_id1{0};
0320     int track_id2{0};
0321     int pid1{0};
0322     int pid2{0};
0323     int parent_id1{0};
0324     int parent_id2{0};
0325     int parent_pid{0};
0326     int kalman_ndof1{0};
0327     int kalman_ndof2{0};
0328     short npoints1{0};
0329     short npoints2{0};
0330   };
0331 
0332   struct TrackRow
0333   {
0334     int run{0};
0335     int evt{0};
0336     int track_id{0};
0337     int shower_id{0};
0338     int pid{0};
0339     int parent_id{0};
0340     int parent_pid{0};
0341     double charge{0.0};
0342     int side{-1};
0343     int npoints{0};
0344     unsigned int ntpc_clusters{0};
0345     int has_helix{0};
0346     int has_kalman{0};
0347     int is_primary{0};
0348 
0349     double px{0.0};
0350     double py{0.0};
0351     double pz{0.0};
0352     double pt{0.0};
0353     double p{0.0};
0354     double eta{0.0};
0355     double dedx{0.0};
0356     float x{0.0F};
0357     float y{0.0F};
0358     float z{0.0F};
0359 
0360     float first_x{0.0F};
0361     float first_y{0.0F};
0362     float first_z{0.0F};
0363     float first_r{0.0F};
0364     float last_x{0.0F};
0365     float last_y{0.0F};
0366     float last_z{0.0F};
0367     float last_r{0.0F};
0368 
0369     float dca_xy{0.0F};
0370     float dca_z{0.0F};
0371     double vertex_x{0.0};
0372     double vertex_y{0.0};
0373     double vertex_z{0.0};
0374     int vertex_from_upstream{0};
0375     double vertex_z_rms{0.0};
0376     unsigned int vertex_ntracks{0};
0377     double pca_x{0.0};
0378     double pca_y{0.0};
0379     double pca_z{0.0};
0380     double rDCA_zero{0.0};
0381     double zDCA{0.0};
0382 
0383     float helix_cx{0.0F};
0384     float helix_cy{0.0F};
0385     float helix_radius{0.0F};
0386     float helix_z0{0.0F};
0387     float helix_pitch{0.0F};
0388     float helix_theta_first{0.0F};
0389     float helix_theta_last{0.0F};
0390     float helix_direction{0.0F};
0391     int helix_search_anchored{0};
0392     int helix_anchor_point_index{-1};
0393     float helix_anchor_theta{0.0F};
0394     float helix_anchor_path_cm{0.0F};
0395     float helix_anchor_residual_cm{0.0F};
0396     float helix_search_theta_min{0.0F};
0397     float helix_search_theta_max{0.0F};
0398     float helix_search_upstream_cm{0.0F};
0399     float helix_search_downstream_cm{0.0F};
0400 
0401     float kalman_chi2{0.0F};
0402     int kalman_ndof{0};
0403     unsigned int kalman_naccepted{0};
0404     unsigned int kalman_nrejected{0};
0405     float kalman_measurement_sigma_r{0.0F};
0406     float kalman_measurement_sigma_rphi{0.0F};
0407     float kalman_measurement_sigma_z{0.0F};
0408     float kalman_qop_t{0.0F};
0409     float kalman_omega{0.0F};
0410     float kalman_cx{0.0F};
0411     float kalman_cy{0.0F};
0412     float kalman_radius{0.0F};
0413     float fit_chi2{0.0F};
0414     int fit_ndf{0};
0415     float quality{0.0F};
0416 
0417     float truth_px{0.0F};
0418     float truth_py{0.0F};
0419     float truth_pz{0.0F};
0420     float cos_mom_truth{0.0F};
0421 
0422     std::vector<unsigned int> cluster_index;
0423     std::vector<int> cluster_side;
0424     std::vector<unsigned int> layer;
0425     std::vector<double> cluster_z;
0426     std::vector<double> cluster_r;
0427     std::vector<double> cluster_phi;
0428     std::vector<double> residual_z;
0429     std::vector<double> residual_r;
0430     std::vector<double> residual_rphi;
0431     std::vector<double> kalman_measurement_chi2;
0432     std::vector<unsigned char> kalman_measurement_used;
0433     std::vector<unsigned char> kalman_measurement_in_seed;
0434     std::vector<double> kalman_innovation_residual_r;
0435     std::vector<double> kalman_innovation_residual_rphi;
0436     std::vector<double> kalman_innovation_residual_z;
0437     std::vector<double> kalman_prediction_sigma_r;
0438     std::vector<double> kalman_prediction_sigma_rphi;
0439     std::vector<double> kalman_prediction_sigma_z;
0440     std::vector<double> kalman_innovation_sigma_r;
0441     std::vector<double> kalman_innovation_sigma_rphi;
0442     std::vector<double> kalman_innovation_sigma_z;
0443     std::vector<double> kalman_innovation_rho_r_rphi;
0444     std::vector<double> kalman_innovation_rho_r_z;
0445     std::vector<double> kalman_innovation_rho_rphi_z;
0446     std::vector<double> kalman_innovation_whitened_0;
0447     std::vector<double> kalman_innovation_whitened_1;
0448     std::vector<double> kalman_innovation_whitened_2;
0449   };
0450 
0451   struct ClusterResidualRow
0452   {
0453     int run{0};
0454     int evt{0};
0455     int track_id{0};
0456     int charge{0};
0457     int side{0};
0458     int layer{0};
0459     int cluster_index{0};
0460     int ntp_cluster{0};
0461     int npoints{0};
0462     int has_helix{0};
0463     int has_kalman{0};
0464 
0465     float cluster_x{0.0F};
0466     float cluster_y{0.0F};
0467     float cluster_z{0.0F};
0468     float cluster_r{0.0F};
0469     float cluster_phi{0.0F};
0470 
0471     float fit_x{0.0F};
0472     float fit_y{0.0F};
0473     float fit_z{0.0F};
0474     float fit_r{0.0F};
0475     float fit_phi{0.0F};
0476 
0477     float residual_x{0.0F};
0478     float residual_y{0.0F};
0479     float residual_z{0.0F};
0480     float residual_r{0.0F};
0481     float residual_rphi{0.0F};
0482 
0483     float fit_chi2{0.0F};
0484     int fit_ndf{0};
0485     float fit_chi2_ndf{0.0F};
0486   };
0487 
0488   int get_event_number(PHCompositeNode *topNode) const;
0489   int get_run_number(PHCompositeNode *topNode) const;
0490   Vec3 get_primary_vertex(PHG4TruthInfoContainer *truth_info) const;
0491   std::map<int, Tracklet> build_tracklets(PHG4HitContainer *truth_points,
0492                                           PHG4TruthInfoContainer *truth_info) const;
0493   std::map<int, Tracklet> build_pattern_tracklets(Tpc_PolyClusterContainer *clusters,
0494                                                   Tpc_PolyTrackContainer *tracks) const;
0495   bool finalize_pattern_tracklet(Tracklet &tracklet, bool has_upstream_state) const;
0496   bool make_pair_row(const Tracklet &track1, const Tracklet &track2,
0497                      const Vec3 &primary_vertex, const int run_number,
0498                      const int event_number);
0499   void fill_track_row(const Tracklet &tracklet, const Vec3 &primary_vertex,
0500                       int run_number, int event_number);
0501   void fill_cluster_residual_rows(const Tracklet &tracklet, const Vec3 &primary_vertex,
0502                                   int run_number, int event_number);
0503   bool track_pca_to_xy(const Tracklet &tracklet, const Vec3 &beamline,
0504                        Vec3 &pca, double &signed_dca_xy) const;
0505   bool choose_pattern_collision_vertex(const Tracklet &tracklet,
0506                                        Tpc_PolyTrackVertexContainer *vertices,
0507                                        Vec3 &vertex, double &z_rms,
0508                                        unsigned int &ntracks) const;
0509   void assign_fit_quality(Tracklet &tracklet) const;
0510   void reset_pair_row();
0511   void reset_track_row();
0512   void reset_cluster_residual_row();
0513   void create_branches();
0514 
0515   static int pdg_charge(int pid);
0516   static bool parse_point_order(const std::string &mode, PointOrder &order);
0517   static float quiet_nan();
0518   static bool finite(const Vec3 &value);
0519   static Vec3 add(const Vec3 &lhs, const Vec3 &rhs);
0520   static Vec3 subtract(const Vec3 &lhs, const Vec3 &rhs);
0521   static Vec3 scale(const Vec3 &value, double factor);
0522   static double dot(const Vec3 &lhs, const Vec3 &rhs);
0523   static Vec3 cross(const Vec3 &lhs, const Vec3 &rhs);
0524   static double norm(const Vec3 &value);
0525   static Vec3 unit(const Vec3 &value);
0526   static double pt(const Vec3 &value);
0527   static double distance(const Vec3 &lhs, const Vec3 &rhs);
0528   static double vector_cosine(const Vec3 &lhs, const Vec3 &rhs);
0529   static bool fit_circle_least_squares(const std::vector<TruthPoint> &points,
0530                                        std::size_t nfit,
0531                                        double &cx,
0532                                        double &cy,
0533                                        double &radius);
0534   static void order_track_points(std::vector<TruthPoint> &points, PointOrder order);
0535 
0536   static bool fit_helix(const std::vector<TruthPoint> &points, int fit_first_points,
0537                         int charge, double bfield_t, HelixFit &helix);
0538   bool fit_kalman(const std::vector<TruthPoint> &points,
0539                   int charge,
0540                   TpcKalmanResult &kalman) const;
0541   static bool helix_from_state(const Vec3 &position, const Vec3 &momentum,
0542                                int charge, double bfield_t, HelixFit &helix);
0543   static Vec3 helix_point(const HelixFit &helix, double theta);
0544   static Vec3 helix_tangent(const HelixFit &helix, double theta);
0545   static Vec3 helix_momentum(const HelixFit &helix, double theta);
0546   static std::pair<double, double> theta_search_range(const HelixFit &helix,
0547                                                       double theta_extension,
0548                                                       double downstream_margin);
0549   static bool line_line_pca(const Vec3 &pos1, const Vec3 &dir1,
0550                             const Vec3 &pos2, const Vec3 &dir2,
0551                             LinePca &pca, bool normalize_dirs);
0552   static HelixPca refine_helix_pair(const HelixFit &helix1, const HelixFit &helix2,
0553                                     double theta1, double theta2,
0554                                     double min1, double max1,
0555                                     double min2, double max2,
0556                                     double max_step);
0557   static std::vector<HelixPca> helix_helix_pca_candidates(const HelixFit &helix1,
0558                                                           const HelixFit &helix2,
0559                                                           double theta_extension,
0560                                                           int coarse_steps,
0561                                                           double downstream_margin,
0562                                                           int max_candidates);
0563   static Vec3 kalman_point(const TpcKalmanResult &kalman,
0564                            double s_cm,
0565                            const TpcKalmanConfig &config,
0566                            const Vec3 &reference_vertex);
0567   static Vec3 kalman_tangent(const TpcKalmanResult &kalman,
0568                              double s_cm,
0569                              const TpcKalmanConfig &config,
0570                              const Vec3 &reference_vertex);
0571   static Vec3 kalman_momentum(const TpcKalmanResult &kalman,
0572                               double s_cm,
0573                               const TpcKalmanConfig &config,
0574                               const Vec3 &reference_vertex);
0575   static KalmanPca refine_kalman_pair(const TpcKalmanResult &kalman1,
0576                                       const TpcKalmanResult &kalman2,
0577                                       const TpcKalmanConfig &config,
0578                                       const Vec3 &reference_vertex,
0579                                       double s1, double s2,
0580                                       double min1, double max1,
0581                                       double min2, double max2,
0582                                       double max_step,
0583                                       int max_iterations = 30);
0584   static std::vector<KalmanPca> kalman_pca_candidates(const TpcKalmanResult &kalman1,
0585                                                       const TpcKalmanResult &kalman2,
0586                                                       const TpcKalmanConfig &config,
0587                                                       const Vec3 &reference_vertex,
0588                                                       double max_upstream_cm,
0589                                                       double downstream_margin_cm,
0590                                                       int coarse_steps,
0591                                                       int max_candidates);
0592   static std::pair<double, double> track_dca_to_vertex(const Vec3 &pos,
0593                                                        const Vec3 &mom,
0594                                                        const Vec3 &vertex);
0595   static std::pair<double, double> helix_dca_to_vertex(const HelixFit &helix,
0596                                                        const Vec3 &vertex);
0597   std::pair<double, double> fitted_track_dca_to_vertex(const Tracklet &tracklet,
0598                                                        const Vec3 &vertex) const;
0599   static bool armenteros(const Vec3 &pplus, const Vec3 &pminus,
0600                          double &alpha, double &qt);
0601   static double invariant_mass(const Vec3 &mom1, double mass1,
0602                                const Vec3 &mom2, double mass2);
0603 
0604   bool passes_preselection(const Tracklet &track1, const Tracklet &track2,
0605                            const Vec3 &primary_vertex) const;
0606   bool passes_pair_selection(const Vec3 &pca1, const Vec3 &pca2,
0607                              const Vec3 &pair_vertex, const Vec3 &primary_vertex,
0608                              double pair_dca, double cos_theta, double alpha) const;
0609 
0610   std::string m_filename;
0611   std::string m_truth_point_node{"G4HIT_TPC_TRUECLUSTER"};
0612   std::string m_truth_info_node{"G4TruthInfo"};
0613   std::string m_tpc_sa_cluster_node{"TPC_POLYCLUSTERS"};
0614   std::string m_tpc_sa_track_node{"TPC_POLYTRACKS"};
0615   std::string m_tpc_sa_track_vertex_node{"TPC_POLYTRACKVERTICES"};
0616   bool m_use_pattern_cluster_tracks{false};
0617 
0618   TFile *m_file{nullptr};
0619   TTree *m_pair_tree{nullptr};
0620   TTree *m_track_tree{nullptr};
0621   TTree *m_cluster_residual_tree{nullptr};
0622   PairRow m_pair;
0623   TrackRow m_track;
0624   ClusterResidualRow m_cluster_residual;
0625 
0626   Vec3 m_fixed_primary_vertex{0.0, 0.0, 0.0};
0627   bool m_use_truth_primary_vertex{true};
0628   int m_min_points{5};
0629   bool m_fit_helix_tracks{true};
0630   bool m_fit_kalman_tracks{false};
0631   bool m_use_final_track_helix{false};
0632   PointOrder m_point_order{PointOrder::Path};
0633   int m_fit_first_points{8};
0634   double m_bfield_t{1.4};
0635   TpcKalmanConfig m_kalman_config;
0636   bool m_use_kalman_field_map{true};
0637   double m_kalman_max_upstream_cm{80.0};
0638   double m_kalman_downstream_margin_cm{5.0};
0639   double m_theta_extension{2.0};
0640   int m_coarse_steps{64};
0641   int m_pca_candidates{32};
0642   double m_downstream_margin{0.2};
0643   double m_final_track_helix_max_upstream_cm{80.0};
0644   double m_final_track_helix_downstream_margin_cm{5.0};
0645   bool m_prefer_positive_pointing{false};
0646   bool m_write_cluster_residual_tree{false};
0647 
0648   double m_pre_track_pt_min{0.2};
0649   double m_pre_track_dca_xy_min{0.03};
0650   double m_pre_track_dca_z_min{-1.0};
0651   double m_pre_track_dca_xy_max{-1.0};
0652   double m_pre_track_dca_z_max{-1.0};
0653   double m_pre_pair_dca_max{5.0};
0654   double m_pre_lproj_min{0.2};
0655   double m_pre_cos_theta_min{-2.0};
0656   double m_pre_track_quality_max{-1.0};
0657   int m_pre_track_npoints_min{0};
0658   double m_pair_pca_z_max{-1.0};
0659   double m_pair_pca_dz_max{-1.0};
0660   double m_pair_decay_radius_min{-1.0};
0661   double m_pair_alpha_abs_max{-1.0};
0662   double m_pair_dca_max{-1.0};
0663   double m_pair_dira_min{-2.0};
0664   bool m_write_same_sign_pairs{false};
0665   bool m_print_timing{false};
0666 
0667   std::uint64_t m_counter_raw_pairs{0};
0668   std::uint64_t m_counter_reject_charge{0};
0669   std::uint64_t m_counter_reject_preselection{0};
0670   std::uint64_t m_counter_reject_pca{0};
0671   std::uint64_t m_counter_reject_pointing{0};
0672   std::uint64_t m_counter_reject_ap{0};
0673   std::uint64_t m_counter_reject_pair_selection{0};
0674   std::uint64_t m_counter_written{0};
0675   std::uint64_t m_counter_tracks_written{0};
0676   std::uint64_t m_counter_cluster_residuals_written{0};
0677   mutable std::uint64_t m_counter_reject_helix_anchor{0};
0678   std::uint64_t m_timing_events{0};
0679   mutable std::uint64_t m_timing_kalman_fits{0};
0680   mutable std::uint64_t m_timing_rkn_propagations{0};
0681   mutable std::uint64_t m_timing_rkn_accepted_steps{0};
0682   mutable std::uint64_t m_timing_rkn_rejected_trials{0};
0683   mutable std::uint64_t m_timing_rkn_failures{0};
0684   double m_timing_total_seconds{0.0};
0685   double m_timing_track_build_seconds{0.0};
0686   mutable double m_timing_kalman_fit_seconds{0.0};
0687   mutable double m_timing_rkn_seconds{0.0};
0688   double m_timing_track_qa_seconds{0.0};
0689   double m_timing_dca_cache_seconds{0.0};
0690   double m_timing_pair_loop_seconds{0.0};
0691   double m_timing_kalman_pca_seconds{0.0};
0692 };
0693 
0694 #endif