File indexing completed on 2024-04-06 12:26:01
0001
0002
0003
0004 #include "RecoLocalMuon/CSCSegment/src/CSCSegFit.h"
0005
0006 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0007
0008 #include "Geometry/CSCGeometry/interface/CSCLayer.h"
0009
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012
0013 void CSCSegFit::fit(void) {
0014 if (fitdone())
0015 return;
0016 short n = nhits();
0017 switch (n) {
0018 case 1:
0019 edm::LogVerbatim("CSCSegFit") << "[CSCSegFit::fit] - cannot fit just 1 hit!!";
0020 break;
0021 case 2:
0022 fit2();
0023 break;
0024 case 3:
0025 case 4:
0026 case 5:
0027 case 6:
0028 fitlsq();
0029 break;
0030 default:
0031 edm::LogVerbatim("CSCSegFit") << "[CSCSegFit::fit] - cannot fit more than 6 hits!!";
0032 }
0033 }
0034
0035 void CSCSegFit::fit2(void) {
0036
0037
0038
0039
0040
0041
0042 CSCSetOfHits::const_iterator ih = hits_.begin();
0043 int il1 = (*ih)->cscDetId().layer();
0044 const CSCRecHit2D& h1 = (**ih);
0045 ++ih;
0046 int il2 = (*ih)->cscDetId().layer();
0047 const CSCRecHit2D& h2 = (**ih);
0048
0049
0050 if (il1 == il2) {
0051 edm::LogVerbatim("CSCSegFit") << "[CSCSegFit:fit]2 - 2 hits on same layer!!";
0052 return;
0053 }
0054
0055 const CSCLayer* layer1 = chamber()->layer(il1);
0056 const CSCLayer* layer2 = chamber()->layer(il2);
0057
0058 GlobalPoint h1glopos = layer1->toGlobal(h1.localPosition());
0059 GlobalPoint h2glopos = layer2->toGlobal(h2.localPosition());
0060
0061
0062 LocalPoint h1pos = chamber()->toLocal(h1glopos);
0063 LocalPoint h2pos = chamber()->toLocal(h2glopos);
0064
0065 float dz = h2pos.z() - h1pos.z();
0066
0067 uslope_ = (h2pos.x() - h1pos.x()) / dz;
0068 vslope_ = (h2pos.y() - h1pos.y()) / dz;
0069
0070 float uintercept = (h1pos.x() * h2pos.z() - h2pos.x() * h1pos.z()) / dz;
0071 float vintercept = (h1pos.y() * h2pos.z() - h2pos.y() * h1pos.z()) / dz;
0072 intercept_ = LocalPoint(uintercept, vintercept, 0.);
0073
0074 setOutFromIP();
0075
0076
0077 chi2_ = 0.;
0078 ndof_ = 0;
0079
0080 fitdone_ = true;
0081 }
0082
0083 void CSCSegFit::fitlsq(void) {
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 SMatrix4 M;
0151 SVector4 B;
0152
0153 CSCSetOfHits::const_iterator ih = hits_.begin();
0154
0155 for (ih = hits_.begin(); ih != hits_.end(); ++ih) {
0156 const CSCRecHit2D& hit = (**ih);
0157 const CSCLayer* layer = chamber()->layer(hit.cscDetId().layer());
0158 GlobalPoint gp = layer->toGlobal(hit.localPosition());
0159 LocalPoint lp = chamber()->toLocal(gp);
0160
0161
0162 double u = lp.x();
0163 double v = lp.y();
0164 double z = lp.z();
0165
0166
0167 SMatrixSym2 IC;
0168
0169 IC(0, 0) = hit.localPositionError().xx();
0170 IC(1, 1) = hit.localPositionError().yy();
0171
0172
0173 IC(1, 0) = hit.localPositionError().xy();
0174
0175
0176
0177 bool ok = IC.Invert();
0178 if (!ok) {
0179 edm::LogVerbatim("CSCSegment|CSCSegFit") << "[CSCSegFit::fit] Failed to invert covariance matrix: \n" << IC;
0180
0181 }
0182
0183 M(0, 0) += IC(0, 0);
0184 M(0, 1) += IC(0, 1);
0185 M(0, 2) += IC(0, 0) * z;
0186 M(0, 3) += IC(0, 1) * z;
0187 B(0) += u * IC(0, 0) + v * IC(0, 1);
0188
0189 M(1, 0) += IC(1, 0);
0190 M(1, 1) += IC(1, 1);
0191 M(1, 2) += IC(1, 0) * z;
0192 M(1, 3) += IC(1, 1) * z;
0193 B(1) += u * IC(1, 0) + v * IC(1, 1);
0194
0195 M(2, 0) += IC(0, 0) * z;
0196 M(2, 1) += IC(0, 1) * z;
0197 M(2, 2) += IC(0, 0) * z * z;
0198 M(2, 3) += IC(0, 1) * z * z;
0199 B(2) += (u * IC(0, 0) + v * IC(0, 1)) * z;
0200
0201 M(3, 0) += IC(1, 0) * z;
0202 M(3, 1) += IC(1, 1) * z;
0203 M(3, 2) += IC(1, 0) * z * z;
0204 M(3, 3) += IC(1, 1) * z * z;
0205 B(3) += (u * IC(1, 0) + v * IC(1, 1)) * z;
0206 }
0207
0208 SVector4 p;
0209 bool ok = M.Invert();
0210 if (!ok) {
0211 edm::LogVerbatim("CSCSegment|CSCSegFit") << "[CSCSegFit::fit] Failed to invert matrix: \n" << M;
0212
0213 } else {
0214 p = M * B;
0215 }
0216
0217
0218
0219
0220
0221
0222 intercept_ = LocalPoint(p(0), p(1), 0.);
0223
0224
0225 uslope_ = p(2);
0226 vslope_ = p(3);
0227 setOutFromIP();
0228
0229
0230 setChi2();
0231
0232
0233 fitdone_ = true;
0234 }
0235
0236 void CSCSegFit::setChi2(void) {
0237 double chsq = 0.;
0238
0239 CSCSetOfHits::const_iterator ih;
0240 for (ih = hits_.begin(); ih != hits_.end(); ++ih) {
0241 const CSCRecHit2D& hit = (**ih);
0242 const CSCLayer* layer = chamber()->layer(hit.cscDetId().layer());
0243 GlobalPoint gp = layer->toGlobal(hit.localPosition());
0244 LocalPoint lp = chamber()->toLocal(gp);
0245
0246 double u = lp.x();
0247 double v = lp.y();
0248 double z = lp.z();
0249
0250 double du = intercept_.x() + uslope_ * z - u;
0251 double dv = intercept_.y() + vslope_ * z - v;
0252
0253
0254
0255 SMatrixSym2 IC;
0256
0257 IC(0, 0) = hit.localPositionError().xx();
0258
0259 IC(1, 0) = hit.localPositionError().xy();
0260 IC(1, 1) = hit.localPositionError().yy();
0261
0262
0263
0264
0265
0266 bool ok = IC.Invert();
0267 if (!ok) {
0268 edm::LogVerbatim("CSCSegment|CSCSegFit") << "[CSCSegFit::setChi2] Failed to invert covariance matrix: \n" << IC;
0269
0270 }
0271
0272 chsq += du * du * IC(0, 0) + 2. * du * dv * IC(0, 1) + dv * dv * IC(1, 1);
0273 }
0274
0275
0276 chi2_ = chsq;
0277 ndof_ = 2. * hits_.size() - 4;
0278
0279
0280 }
0281
0282 CSCSegFit::SMatrixSym12 CSCSegFit::weightMatrix() {
0283 bool ok = true;
0284
0285 SMatrixSym12 matrix = ROOT::Math::SMatrixIdentity();
0286
0287 int row = 0;
0288
0289 for (CSCSetOfHits::const_iterator it = hits_.begin(); it != hits_.end(); ++it) {
0290 const CSCRecHit2D& hit = (**it);
0291
0292
0293
0294 matrix(row, row) = scaleXError() * hit.localPositionError().xx();
0295 matrix(row, row + 1) = hit.localPositionError().xy();
0296 ++row;
0297 matrix(row, row - 1) = hit.localPositionError().xy();
0298 matrix(row, row) = hit.localPositionError().yy();
0299 ++row;
0300 }
0301
0302 ok = matrix.Invert();
0303 if (!ok) {
0304 edm::LogVerbatim("CSCSegment|CSCSegFit") << "[CSCSegFit::weightMatrix] Failed to invert matrix: \n" << matrix;
0305
0306 }
0307 return matrix;
0308 }
0309
0310 CSCSegFit::SMatrix12by4 CSCSegFit::derivativeMatrix() {
0311 SMatrix12by4 matrix;
0312 int row = 0;
0313
0314 for (CSCSetOfHits::const_iterator it = hits_.begin(); it != hits_.end(); ++it) {
0315 const CSCRecHit2D& hit = (**it);
0316 const CSCLayer* layer = chamber()->layer(hit.cscDetId().layer());
0317 GlobalPoint gp = layer->toGlobal(hit.localPosition());
0318 LocalPoint lp = chamber()->toLocal(gp);
0319 float z = lp.z();
0320
0321 matrix(row, 0) = 1.;
0322 matrix(row, 2) = z;
0323 ++row;
0324 matrix(row, 1) = 1.;
0325 matrix(row, 3) = z;
0326 ++row;
0327 }
0328 return matrix;
0329 }
0330
0331 void CSCSegFit::setOutFromIP() {
0332
0333
0334
0335 double dxdz = uslope_;
0336 double dydz = vslope_;
0337 double dz = 1. / sqrt(1. + dxdz * dxdz + dydz * dydz);
0338 double dx = dz * dxdz;
0339 double dy = dz * dydz;
0340 LocalVector localDir(dx, dy, dz);
0341
0342
0343
0344
0345
0346 double globalZpos = (chamber()->toGlobal(intercept_)).z();
0347 double globalZdir = (chamber()->toGlobal(localDir)).z();
0348 double directionSign = globalZpos * globalZdir;
0349 localdir_ = (directionSign * localDir).unit();
0350 }
0351
0352 AlgebraicSymMatrix CSCSegFit::covarianceMatrix() {
0353 SMatrixSym12 weights = weightMatrix();
0354 SMatrix12by4 A = derivativeMatrix();
0355
0356
0357
0358
0359
0360
0361 bool ok;
0362 SMatrixSym4 result = ROOT::Math::SimilarityT(A, weights);
0363
0364 ok = result.Invert();
0365 if (!ok) {
0366 edm::LogVerbatim("CSCSegment|CSCSegFit") << "[CSCSegFit::calculateError] Failed to invert matrix: \n" << result;
0367
0368 }
0369
0370
0371
0372
0373 AlgebraicSymMatrix flipped = flipErrors(result);
0374
0375 return flipped;
0376 }
0377
0378 AlgebraicSymMatrix CSCSegFit::flipErrors(const SMatrixSym4& a) {
0379
0380
0381
0382
0383
0384
0385 AlgebraicSymMatrix hold(4, 0.);
0386
0387 for (short j = 0; j != 4; ++j) {
0388 for (short i = 0; i != 4; ++i) {
0389 hold(i + 1, j + 1) = a(i, j);
0390 }
0391 }
0392
0393
0394
0395
0396
0397
0398
0399
0400 hold(1, 1) = a(2, 2);
0401 hold(1, 2) = a(2, 3);
0402 hold(2, 1) = a(3, 2);
0403 hold(2, 2) = a(3, 3);
0404
0405
0406 hold(3, 3) = a(0, 0);
0407 hold(3, 4) = a(0, 1);
0408 hold(4, 3) = a(1, 0);
0409 hold(4, 4) = a(1, 1);
0410
0411
0412 hold(4, 1) = a(1, 2);
0413 hold(3, 2) = a(0, 3);
0414 hold(2, 3) = a(3, 0);
0415 hold(1, 4) = a(2, 1);
0416
0417
0418
0419
0420
0421
0422
0423 return hold;
0424 }
0425
0426 float CSCSegFit::xfit(float z) const {
0427
0428
0429 return intercept_.x() + uslope_ * z;
0430 }
0431
0432 float CSCSegFit::yfit(float z) const { return intercept_.y() + vslope_ * z; }
0433
0434 float CSCSegFit::xdev(float x, float z) const { return intercept_.x() + uslope_ * z - x; }
0435
0436 float CSCSegFit::ydev(float y, float z) const { return intercept_.y() + vslope_ * z - y; }
0437
0438 float CSCSegFit::Rdev(float x, float y, float z) const {
0439 return sqrt(xdev(x, z) * xdev(x, z) + ydev(y, z) * ydev(y, z));
0440 }