Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:27:40

0001 /****************************************************************************
0002 *
0003 * This is a part of TOTEM offline software.
0004 * Authors:
0005 *   Hubert Niewiadomski
0006 *   Jan Kašpar (jan.kaspar@gmail.com)
0007 *
0008 ****************************************************************************/
0009 
0010 #include "RecoPPS/Local/interface/TotemRPLocalTrackFitterAlgorithm.h"
0011 
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 
0014 #include "TMatrixD.h"
0015 
0016 //----------------------------------------------------------------------------------------------------
0017 
0018 using namespace std;
0019 using namespace edm;
0020 
0021 //----------------------------------------------------------------------------------------------------
0022 
0023 TotemRPLocalTrackFitterAlgorithm::TotemRPLocalTrackFitterAlgorithm(const edm::ParameterSet &) {}
0024 
0025 //----------------------------------------------------------------------------------------------------
0026 
0027 void TotemRPLocalTrackFitterAlgorithm::reset() { det_data_map_.clear(); }
0028 
0029 //----------------------------------------------------------------------------------------------------
0030 
0031 TotemRPLocalTrackFitterAlgorithm::RPDetCoordinateAlgebraObjs
0032 TotemRPLocalTrackFitterAlgorithm::prepareReconstAlgebraData(unsigned int det_id, const CTPPSGeometry &tot_rp_geom) {
0033   RPDetCoordinateAlgebraObjs det_algebra_obj;
0034 
0035   det_algebra_obj.centre_of_det_global_position_ = convert3vector(tot_rp_geom.sensorTranslation(det_id));
0036 
0037   TVector3 rd_dir = convert3vector(tot_rp_geom.localToGlobalDirection(det_id, rp_topology_.GetStripReadoutAxisDir()));
0038 
0039   TVector2 v(rd_dir.X(), rd_dir.Y());
0040   det_algebra_obj.readout_direction_ = v.Unit();
0041   det_algebra_obj.rec_u_0_ = 0.0;
0042   det_algebra_obj.available_ = true;
0043   det_algebra_obj.rec_u_0_ =
0044       -(det_algebra_obj.readout_direction_ * det_algebra_obj.centre_of_det_global_position_.XYvector());
0045 
0046   return det_algebra_obj;
0047 }
0048 
0049 //----------------------------------------------------------------------------------------------------
0050 
0051 TotemRPLocalTrackFitterAlgorithm::RPDetCoordinateAlgebraObjs *TotemRPLocalTrackFitterAlgorithm::getDetAlgebraData(
0052     unsigned int det_id, const CTPPSGeometry &tot_rp_geom) {
0053   auto it = det_data_map_.find(det_id);
0054   if (it != det_data_map_.end()) {
0055     return &(it->second);
0056   } else {
0057     det_data_map_[det_id] = prepareReconstAlgebraData(det_id, tot_rp_geom);
0058     return &det_data_map_[det_id];
0059   }
0060 }
0061 
0062 //----------------------------------------------------------------------------------------------------
0063 
0064 bool TotemRPLocalTrackFitterAlgorithm::fitTrack(const edm::DetSetVector<TotemRPRecHit> &hits,
0065                                                 double z_0,
0066                                                 const CTPPSGeometry &tot_geom,
0067                                                 TotemRPLocalTrack &fitted_track) {
0068   fitted_track.setValid(false);
0069 
0070   // bind hits with their algebra objects
0071   struct HitWithAlg {
0072     unsigned int detId;
0073     const TotemRPRecHit *hit;
0074     RPDetCoordinateAlgebraObjs *alg;
0075   };
0076 
0077   vector<HitWithAlg> applicable_hits;
0078 
0079   for (auto &ds : hits) {
0080     unsigned int detId = ds.detId();
0081 
0082     for (auto &h : ds) {
0083       RPDetCoordinateAlgebraObjs *alg = getDetAlgebraData(detId, tot_geom);
0084       if (alg->available_)
0085         applicable_hits.push_back({detId, &h, alg});
0086     }
0087   }
0088 
0089   if (applicable_hits.size() < 5)
0090     return false;
0091 
0092   TMatrixD H(applicable_hits.size(), 4);
0093   TVectorD V(applicable_hits.size());
0094   TVectorD V_inv(applicable_hits.size());
0095   TVectorD U(applicable_hits.size());
0096 
0097   for (unsigned int i = 0; i < applicable_hits.size(); ++i) {
0098     RPDetCoordinateAlgebraObjs *alg_obj = applicable_hits[i].alg;
0099 
0100     H(i, 0) = alg_obj->readout_direction_.X();
0101     H(i, 1) = alg_obj->readout_direction_.Y();
0102     double delta_z = alg_obj->centre_of_det_global_position_.Z() - z_0;
0103     H(i, 2) = alg_obj->readout_direction_.X() * delta_z;
0104     H(i, 3) = alg_obj->readout_direction_.Y() * delta_z;
0105     double var = applicable_hits[i].hit->sigma();
0106     var *= var;
0107     V[i] = var;
0108     V_inv[i] = 1.0 / var;
0109     U[i] = applicable_hits[i].hit->position() - alg_obj->rec_u_0_;
0110   }
0111 
0112   TMatrixD H_T_V_inv(TMatrixD::kTransposed, H);
0113   multiplyByDiagonalInPlace(H_T_V_inv, V_inv);
0114   TMatrixD V_a(H_T_V_inv);
0115   TMatrixD V_a_mult(V_a, TMatrixD::kMult, H);
0116   try {
0117     V_a_mult.Invert();
0118   } catch (cms::Exception &e) {
0119     LogError("TotemRPLocalTrackFitterAlgorithm") << "Error in TotemRPLocalTrackFitterAlgorithm::fitTrack > "
0120                                                  << "Fit matrix is singular. Skipping.";
0121     return false;
0122   }
0123 
0124   TMatrixD u_to_a(V_a_mult, TMatrixD::kMult, H_T_V_inv);
0125   TVectorD a(U);
0126   a *= u_to_a;
0127 
0128   fitted_track.setZ0(z_0);
0129   fitted_track.setParameterVector(a);
0130   fitted_track.setCovarianceMatrix(V_a_mult);
0131 
0132   double Chi_2 = 0;
0133   for (unsigned int i = 0; i < applicable_hits.size(); ++i) {
0134     RPDetCoordinateAlgebraObjs *alg_obj = applicable_hits[i].alg;
0135     TVector2 readout_dir = alg_obj->readout_direction_;
0136     double det_z = alg_obj->centre_of_det_global_position_.Z();
0137     double sigma_str = applicable_hits[i].hit->sigma();
0138     double sigma_str_2 = sigma_str * sigma_str;
0139     TVector2 fited_det_xy_point = fitted_track.trackPoint(det_z);
0140     double U_readout = applicable_hits[i].hit->position() - alg_obj->rec_u_0_;
0141     double U_fited = (readout_dir *= fited_det_xy_point);
0142     double residual = U_fited - U_readout;
0143     TMatrixD V_T_Cov_X_Y(1, 2);
0144     V_T_Cov_X_Y(0, 0) = readout_dir.X();
0145     V_T_Cov_X_Y(0, 1) = readout_dir.Y();
0146     TMatrixD V_T_Cov_X_Y_mult(V_T_Cov_X_Y, TMatrixD::kMult, fitted_track.trackPointInterpolationCovariance(det_z));
0147     double fit_strip_var = V_T_Cov_X_Y_mult(0, 0) * readout_dir.X() + V_T_Cov_X_Y_mult(0, 1) * readout_dir.Y();
0148     double pull_normalization = sqrt(sigma_str_2 - fit_strip_var);
0149     double pull = residual / pull_normalization;
0150 
0151     Chi_2 += residual * residual / sigma_str_2;
0152 
0153     TotemRPLocalTrack::FittedRecHit hit_point(
0154         *(applicable_hits[i].hit), TVector3(fited_det_xy_point.X(), fited_det_xy_point.Y(), det_z), residual, pull);
0155     fitted_track.addHit(applicable_hits[i].detId, hit_point);
0156   }
0157 
0158   fitted_track.setChiSquared(Chi_2);
0159   fitted_track.setValid(true);
0160   return true;
0161 }
0162 
0163 //----------------------------------------------------------------------------------------------------
0164 
0165 void TotemRPLocalTrackFitterAlgorithm::multiplyByDiagonalInPlace(TMatrixD &mt, const TVectorD &diag) {
0166   for (int i = 0; i < mt.GetNrows(); ++i) {
0167     for (int j = 0; j < mt.GetNcols(); ++j) {
0168       mt[i][j] *= diag[j];
0169     }
0170   }
0171 }