File indexing completed on 2024-04-06 12:26:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "RecoLocalMuon/DTSegment/src/DTSegmentUpdator.h"
0012
0013
0014
0015
0016 #include "DataFormats/DTRecHit/interface/DTChamberRecSegment2D.h"
0017
0018 #include "DataFormats/DTRecHit/interface/DTRecSegment2D.h"
0019 #include "DataFormats/DTRecHit/interface/DTSLRecSegment2D.h"
0020 #include "DataFormats/DTRecHit/interface/DTChamberRecSegment2D.h"
0021 #include "DataFormats/DTRecHit/interface/DTRecSegment4D.h"
0022 #include "DataFormats/DTRecHit/interface/DTRecHit1D.h"
0023 #include "DataFormats/GeometryCommonDetAlgo/interface/ErrorFrameTransformer.h"
0024
0025 #include "RecoLocalMuon/DTSegment/src/DTSegmentCand.h"
0026 #include "RecoLocalMuon/DTRecHit/interface/DTRecHitAlgoFactory.h"
0027 #include "RecoLocalMuon/DTSegment/src/DTLinearFit.h"
0028
0029 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0030 #include "Geometry/DTGeometry/interface/DTGeometry.h"
0031 #include "Geometry/DTGeometry/interface/DTLayer.h"
0032
0033 #include "FWCore/Utilities/interface/Exception.h"
0034 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0035 #include "FWCore/Framework/interface/EventSetup.h"
0036 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0037
0038
0039 #include <string>
0040
0041 using namespace std;
0042 using namespace edm;
0043
0044
0045
0046
0047 DTSegmentUpdator::DTSegmentUpdator(const ParameterSet& config, edm::ConsumesCollector cc)
0048 : theFitter{std::make_unique<DTLinearFit>()},
0049 theAlgo{DTRecHitAlgoFactory::get()->create(
0050 config.getParameter<string>("recAlgo"), config.getParameter<ParameterSet>("recAlgoConfig"), cc)},
0051 theGeomToken(cc.esConsumes()),
0052 vdrift_4parfit(config.getParameter<bool>("performT0_vdriftSegCorrection")),
0053 T0_hit_resolution(config.getParameter<double>("hit_afterT0_resolution")),
0054 perform_delta_rejecting(config.getParameter<bool>("perform_delta_rejecting")),
0055 debug(config.getUntrackedParameter<bool>("debug", false)) {
0056 intime_cut = 20.;
0057 if (config.exists("intime_cut"))
0058 intime_cut = config.getParameter<double>("intime_cut");
0059
0060 if (debug)
0061 cout << "[DTSegmentUpdator] Constructor called" << endl;
0062 }
0063
0064
0065 DTSegmentUpdator::~DTSegmentUpdator() = default;
0066
0067
0068
0069 void DTSegmentUpdator::setES(const EventSetup& setup) {
0070 theGeom = setup.getHandle(theGeomToken);
0071 theAlgo->setES(setup);
0072 }
0073
0074 void DTSegmentUpdator::update(DTRecSegment4D* seg, const bool calcT0, bool allow3par) const {
0075 if (debug)
0076 cout << "[DTSegmentUpdator] Starting to update the DTRecSegment4D" << endl;
0077
0078 const bool hasPhi = seg->hasPhi();
0079 const bool hasZed = seg->hasZed();
0080
0081
0082 if (perform_delta_rejecting && hasPhi)
0083 rejectBadHits(seg->phiSegment());
0084
0085 int step = (hasPhi && hasZed) ? 3 : 2;
0086 if (calcT0)
0087 step = 4;
0088
0089 if (debug)
0090 cout << "Step of update is " << step << endl;
0091
0092 GlobalPoint pos = theGeom->idToDet(seg->geographicalId())->toGlobal(seg->localPosition());
0093 GlobalVector dir = theGeom->idToDet(seg->geographicalId())->toGlobal(seg->localDirection());
0094
0095 if (calcT0)
0096 calculateT0corr(seg);
0097
0098 if (hasPhi)
0099 updateHits(seg->phiSegment(), pos, dir, step);
0100 if (hasZed)
0101 updateHits(seg->zSegment(), pos, dir, step);
0102
0103 fit(seg, allow3par);
0104 }
0105
0106 void DTSegmentUpdator::update(DTRecSegment2D* seg, bool allow3par) const {
0107 if (debug)
0108 cout << "[DTSegmentUpdator] Starting to update the DTRecSegment2D" << endl;
0109 GlobalPoint pos = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localPosition());
0110 GlobalVector dir = (theGeom->idToDet(seg->geographicalId()))->toGlobal(seg->localDirection());
0111
0112 updateHits(seg, pos, dir);
0113 fit(seg, allow3par, false);
0114 }
0115
0116 void DTSegmentUpdator::fit(DTRecSegment4D* seg, bool allow3par) const {
0117 if (debug)
0118 cout << "[DTSegmentUpdator] Fit DTRecSegment4D:" << endl;
0119
0120
0121 if (debug) {
0122 if (seg->hasPhi())
0123 cout << " 4D Segment contains a Phi segment. t0= " << seg->phiSegment()->t0()
0124 << " chi2= " << seg->phiSegment()->chi2() << endl;
0125 if (seg->hasZed())
0126 cout << " 4D Segment contains a Zed segment. t0= " << seg->zSegment()->t0()
0127 << " chi2= " << seg->zSegment()->chi2() << endl;
0128 }
0129
0130
0131
0132 if (seg->hasPhi()) {
0133 if (seg->hasZed()) {
0134 if (fabs(seg->phiSegment()->t0()) < intime_cut) {
0135 fit(seg->phiSegment(), allow3par, true);
0136 fit(seg->zSegment(), allow3par, true);
0137 } else {
0138 fit(seg->phiSegment(), allow3par, false);
0139 fit(seg->zSegment(), allow3par, false);
0140 }
0141 } else
0142 fit(seg->phiSegment(), allow3par, false);
0143 } else
0144 fit(seg->zSegment(), allow3par, false);
0145
0146 const DTChamber* theChamber = theGeom->chamber(seg->chamberId());
0147
0148 if (seg->hasPhi() && seg->hasZed()) {
0149 DTChamberRecSegment2D* segPhi = seg->phiSegment();
0150 DTSLRecSegment2D* segZed = seg->zSegment();
0151
0152
0153 LocalPoint posPhiInCh = segPhi->localPosition();
0154 LocalVector dirPhiInCh = segPhi->localDirection();
0155
0156
0157 const DTSuperLayer* zSL = theChamber->superLayer(segZed->superLayerId());
0158 LocalPoint zPos(segZed->localPosition().x(), (zSL->toLocal(theChamber->toGlobal(segPhi->localPosition()))).y(), 0.);
0159
0160 LocalPoint posZInCh = theChamber->toLocal(zSL->toGlobal(zPos));
0161
0162 LocalVector dirZInCh = theChamber->toLocal(zSL->toGlobal(segZed->localDirection()));
0163
0164 LocalPoint posZAt0 = posZInCh + dirZInCh * (-posZInCh.z()) / cos(dirZInCh.theta());
0165
0166
0167
0168 LocalVector dir = LocalVector(dirPhiInCh.x() / fabs(dirPhiInCh.z()), dirZInCh.y() / fabs(dirZInCh.z()), -1.);
0169
0170 seg->setPosition(LocalPoint(posPhiInCh.x(), posZAt0.y(), 0.));
0171 seg->setDirection(dir.unit());
0172
0173 AlgebraicSymMatrix mat(4);
0174
0175
0176 mat[0][0] = segPhi->parametersError()[0][0];
0177 mat[0][2] = segPhi->parametersError()[0][1];
0178 mat[2][2] = segPhi->parametersError()[1][1];
0179
0180 seg->setCovMatrix(mat);
0181 seg->setCovMatrixForZed(posZInCh);
0182 } else if (seg->hasPhi()) {
0183 DTChamberRecSegment2D* segPhi = seg->phiSegment();
0184
0185 seg->setPosition(segPhi->localPosition());
0186 seg->setDirection(segPhi->localDirection());
0187
0188 AlgebraicSymMatrix mat(4);
0189
0190 mat[0][0] = segPhi->parametersError()[0][0];
0191 mat[0][2] = segPhi->parametersError()[0][1];
0192 mat[2][2] = segPhi->parametersError()[1][1];
0193
0194 seg->setCovMatrix(mat);
0195 } else if (seg->hasZed()) {
0196 DTSLRecSegment2D* segZed = seg->zSegment();
0197
0198
0199 GlobalPoint glbPosZ = (theGeom->superLayer(segZed->superLayerId()))->toGlobal(segZed->localPosition());
0200 LocalPoint posZInCh = (theGeom->chamber(segZed->superLayerId().chamberId()))->toLocal(glbPosZ);
0201
0202 GlobalVector glbDirZ = (theGeom->superLayer(segZed->superLayerId()))->toGlobal(segZed->localDirection());
0203 LocalVector dirZInCh = (theGeom->chamber(segZed->superLayerId().chamberId()))->toLocal(glbDirZ);
0204
0205 LocalPoint posZAt0 = posZInCh + dirZInCh * (-posZInCh.z()) / cos(dirZInCh.theta());
0206
0207 seg->setPosition(posZAt0);
0208 seg->setDirection(dirZInCh);
0209
0210 AlgebraicSymMatrix mat(4);
0211
0212 seg->setCovMatrix(mat);
0213 seg->setCovMatrixForZed(posZInCh);
0214 }
0215 }
0216
0217 bool DTSegmentUpdator::fit(DTSegmentCand* seg, bool allow3par, const bool fitdebug) const {
0218
0219
0220
0221
0222
0223
0224
0225 vector<float> x;
0226 vector<float> y;
0227 vector<float> sigy;
0228 vector<int> lfit;
0229 vector<double> dist;
0230
0231 x.reserve(8);
0232 y.reserve(8);
0233 sigy.reserve(8);
0234 lfit.reserve(8);
0235 dist.reserve(8);
0236
0237 for (DTSegmentCand::AssPointCont::const_iterator iter = seg->hits().begin(); iter != seg->hits().end(); ++iter) {
0238 LocalPoint pos = (*iter).first->localPosition((*iter).second);
0239 float xwire =
0240 (((*iter).first)->localPosition(DTEnums::Left).x() + ((*iter).first)->localPosition(DTEnums::Right).x()) / 2.;
0241 float distance = pos.x() - xwire;
0242
0243 if ((*iter).second == DTEnums::Left)
0244 lfit.push_back(1);
0245 else
0246 lfit.push_back(-1);
0247
0248 dist.push_back(distance);
0249 sigy.push_back(sqrt((*iter).first->localPositionError().xx()));
0250 x.push_back(pos.z());
0251 y.push_back(pos.x());
0252 }
0253
0254 LocalPoint pos;
0255 LocalVector dir;
0256 AlgebraicSymMatrix covMat(2);
0257 float cminf = 0.;
0258 float vminf = 0.;
0259 double chi2 = 0.;
0260 double t0_corr = 0.;
0261
0262 fit(x, y, lfit, dist, sigy, pos, dir, cminf, vminf, covMat, chi2, allow3par);
0263 if (cminf != 0)
0264 t0_corr = -cminf / 0.00543;
0265
0266 if (debug && fitdebug)
0267 cout << " DTcand chi2: " << chi2 << "/" << x.size() << " t0: " << t0_corr << endl;
0268
0269 seg->setPosition(pos);
0270 seg->setDirection(dir);
0271 seg->sett0(t0_corr);
0272 seg->setCovMatrix(covMat);
0273 seg->setChi2(chi2);
0274
0275
0276
0277
0278
0279 return true;
0280 }
0281
0282 void DTSegmentUpdator::fit(DTRecSegment2D* seg, bool allow3par, bool block3par) const {
0283 if (debug)
0284 cout << "[DTSegmentUpdator] Fit DTRecSegment2D - 3par: " << allow3par << endl;
0285
0286 vector<float> x;
0287 vector<float> y;
0288 vector<float> sigy;
0289 vector<int> lfit;
0290 vector<double> dist;
0291 x.reserve(8);
0292 y.reserve(8);
0293 sigy.reserve(8);
0294 lfit.reserve(8);
0295 dist.reserve(8);
0296
0297
0298
0299
0300
0301 vector<DTRecHit1D> hits = seg->specificRecHits();
0302 for (vector<DTRecHit1D>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
0303
0304 GlobalPoint glbPos = (theGeom->layer(hit->wireId().layerId()))->toGlobal(hit->localPosition());
0305 LocalPoint pos = (theGeom->idToDet(seg->geographicalId()))->toLocal(glbPos);
0306 x.push_back(pos.z());
0307 y.push_back(pos.x());
0308
0309 const DTLayer* layer = theGeom->layer(hit->wireId().layerId());
0310 float xwire = layer->specificTopology().wirePosition(hit->wireId().wire());
0311 float distance = fabs(hit->localPosition().x() - xwire);
0312 dist.push_back(distance);
0313
0314 int ilc = (hit->lrSide() == DTEnums::Left) ? 1 : -1;
0315 lfit.push_back(ilc);
0316
0317
0318
0319 ErrorFrameTransformer tran;
0320 GlobalError glbErr =
0321 tran.transform(hit->localPositionError(), (theGeom->layer(hit->wireId().layerId()))->surface());
0322 LocalError slErr = tran.transform(glbErr, (theGeom->idToDet(seg->geographicalId()))->surface());
0323 sigy.push_back(sqrt(slErr.xx()));
0324 }
0325
0326 LocalPoint pos;
0327 LocalVector dir;
0328 AlgebraicSymMatrix covMat(2);
0329 double chi2 = 0.;
0330 float cminf = 0.;
0331 float vminf = 0.;
0332 double t0_corr = 0.;
0333
0334 fit(x, y, lfit, dist, sigy, pos, dir, cminf, vminf, covMat, chi2, allow3par, block3par);
0335 if (cminf != 0)
0336 t0_corr = -cminf / 0.00543;
0337
0338 if (debug)
0339 cout << " DTSeg2d chi2: " << chi2 << endl;
0340 if (debug)
0341 cout << " DTSeg2d Fit t0: " << t0_corr << endl;
0342
0343
0344
0345
0346 seg->setPosition(pos);
0347 seg->setDirection(dir);
0348 seg->setCovMatrix(covMat);
0349 seg->setChi2(chi2);
0350 seg->setT0(t0_corr);
0351 }
0352
0353 void DTSegmentUpdator::fit(const vector<float>& x,
0354 const vector<float>& y,
0355 const vector<int>& lfit,
0356 const vector<double>& dist,
0357 const vector<float>& sigy,
0358 LocalPoint& pos,
0359 LocalVector& dir,
0360 float& cminf,
0361 float& vminf,
0362 AlgebraicSymMatrix& covMatrix,
0363 double& chi2,
0364 const bool allow3par,
0365 const bool block3par) const {
0366 float slope = 0.;
0367 float intercept = 0.;
0368 float covss = 0.;
0369 float covii = 0.;
0370 float covsi = 0.;
0371
0372 cminf = 0;
0373 vminf = 0;
0374
0375 int leftHits = 0, rightHits = 0;
0376 for (unsigned int i = 0; i < lfit.size(); i++)
0377 if (lfit[i] == 1)
0378 leftHits++;
0379 else
0380 rightHits++;
0381
0382 theFitter->fit(x, y, x.size(), sigy, slope, intercept, chi2, covss, covii, covsi);
0383
0384
0385
0386 if (leftHits && rightHits && (leftHits + rightHits > 3) && allow3par) {
0387 theFitter->fitNpar(3, x, y, lfit, dist, sigy, slope, intercept, cminf, vminf, chi2, debug);
0388 double t0_corr = -cminf / 0.00543;
0389 if (fabs(t0_corr) < intime_cut && block3par) {
0390 theFitter->fit(x, y, x.size(), sigy, slope, intercept, chi2, covss, covii, covsi);
0391 cminf = 0;
0392 }
0393 }
0394
0395
0396
0397
0398
0399
0400
0401 pos = LocalPoint(intercept, 0., 0.);
0402
0403
0404
0405 dir = LocalVector(-slope, 0., -1.).unit();
0406
0407 covMatrix = AlgebraicSymMatrix(2);
0408 covMatrix[0][0] = covss;
0409 covMatrix[1][1] = covii;
0410 covMatrix[1][0] = covsi;
0411 }
0412
0413
0414
0415 void DTSegmentUpdator::updateHits(DTRecSegment2D* seg, GlobalPoint& gpos, GlobalVector& gdir, const int step) const {
0416
0417
0418
0419 vector<DTRecHit1D> toBeUpdatedRecHits = seg->specificRecHits();
0420 vector<DTRecHit1D> updatedRecHits;
0421
0422 for (vector<DTRecHit1D>::iterator hit = toBeUpdatedRecHits.begin(); hit != toBeUpdatedRecHits.end(); ++hit) {
0423 const DTLayer* layer = theGeom->layer(hit->wireId().layerId());
0424
0425 LocalPoint segPos = layer->toLocal(gpos);
0426 LocalVector segDir = layer->toLocal(gdir);
0427
0428
0429 const float angle = atan(segDir.x() / -segDir.z());
0430
0431
0432 LocalPoint segPosAtLayer = segPos + segDir * (-segPos.z()) / cos(segDir.theta());
0433
0434 DTRecHit1D newHit1D = (*hit);
0435 bool ok = true;
0436
0437 if (step == 2) {
0438 ok = theAlgo->compute(layer, *hit, angle, newHit1D);
0439
0440 } else if (step == 3) {
0441 LocalPoint hitPos(hit->localPosition().x(), +segPosAtLayer.y(), 0.);
0442 GlobalPoint glbpos = theGeom->layer(hit->wireId().layerId())->toGlobal(hitPos);
0443 newHit1D.setPosition(hitPos);
0444 ok = theAlgo->compute(layer, *hit, angle, glbpos, newHit1D);
0445
0446 } else if (step == 4) {
0447
0448 double vminf = 0.;
0449 if (vdrift_4parfit)
0450 vminf = seg->vDrift();
0451
0452 double cminf = 0.;
0453 if (seg->ist0Valid())
0454 cminf = -seg->t0() * 0.00543;
0455
0456
0457
0458
0459
0460 const float xwire = layer->specificTopology().wirePosition(hit->wireId().wire());
0461 const float distance = fabs(hit->localPosition().x() - xwire);
0462 const int ilc = (hit->lrSide() == DTEnums::Left) ? 1 : -1;
0463 const double dy_corr = (vminf * ilc * distance - cminf * ilc);
0464
0465 LocalPoint point(hit->localPosition().x() + dy_corr, +segPosAtLayer.y(), 0.);
0466
0467
0468
0469
0470 LocalError error(T0_hit_resolution * T0_hit_resolution, 0., 0.);
0471 newHit1D.setPositionAndError(point, error);
0472
0473
0474 ok = true;
0475
0476 } else
0477 throw cms::Exception("DTSegmentUpdator") << " updateHits called with wrong step " << endl;
0478
0479 if (ok)
0480 updatedRecHits.push_back(newHit1D);
0481 else {
0482 LogError("DTSegmentUpdator") << "DTSegmentUpdator::updateHits failed update" << endl;
0483 throw cms::Exception("DTSegmentUpdator") << "updateHits failed update" << endl;
0484 }
0485 }
0486 seg->update(updatedRecHits);
0487 }
0488
0489 void DTSegmentUpdator::rejectBadHits(DTChamberRecSegment2D* phiSeg) const {
0490 vector<float> x;
0491 vector<float> y;
0492
0493 if (debug)
0494 cout << " Inside the segment updator, now loop on hits: ( x == z_loc , y == x_loc) " << endl;
0495
0496 vector<DTRecHit1D> hits = phiSeg->specificRecHits();
0497 const size_t N = hits.size();
0498 if (N < 3)
0499 return;
0500
0501 for (vector<DTRecHit1D>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
0502
0503 GlobalPoint glbPos = (theGeom->layer(hit->wireId().layerId()))->toGlobal(hit->localPosition());
0504 LocalPoint pos = (theGeom->idToDet(phiSeg->geographicalId()))->toLocal(glbPos);
0505
0506 x.push_back(pos.z());
0507 y.push_back(pos.x());
0508 }
0509
0510 if (debug) {
0511 cout << " end of segment! " << endl;
0512 cout << " size = Number of Hits: " << x.size() << " " << y.size() << endl;
0513 }
0514
0515
0516 float par[2] = {0., 0.};
0517
0518
0519 float Sx = 0.;
0520 float Sy = 0.;
0521 float Sx2 = 0.;
0522 float Sxy = 0.;
0523
0524 for (size_t i = 0; i < N; ++i) {
0525 Sx += x.at(i);
0526 Sy += y.at(i);
0527 Sx2 += x.at(i) * x.at(i);
0528 Sxy += x.at(i) * y.at(i);
0529 }
0530
0531 const float delta = N * Sx2 - Sx * Sx;
0532 par[0] = (Sx2 * Sy - Sx * Sxy) / delta;
0533 par[1] = (N * Sxy - Sx * Sy) / delta;
0534
0535 if (debug)
0536 cout << "fit 2 parameters done ----> par0: " << par[0] << " par1: " << par[1] << endl;
0537
0538
0539 float residuals[N];
0540 float mean_residual = 0.;
0541 for (size_t i = 0; i < N; ++i) {
0542 residuals[i] = y.at(i) - par[1] * x.at(i) - par[0];
0543 mean_residual += std::abs(residuals[i]);
0544 if (debug) {
0545 cout << " i: " << i << " y_i " << y.at(i) << " x_i " << x.at(i) << " res_i " << residuals[i];
0546 if (i == N - 1)
0547 cout << endl;
0548 }
0549 }
0550
0551 if (debug)
0552 cout << " Residuals computed! " << endl;
0553
0554 mean_residual = mean_residual / (N - 2);
0555 if (debug)
0556 cout << " mean_residual: " << mean_residual << endl;
0557
0558 int i = 0;
0559
0560
0561 vector<DTRecHit1D> updatedRecHits;
0562 for (vector<DTRecHit1D>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
0563 float normResidual = mean_residual > 0 ? std::abs(residuals[i]) / mean_residual : 0;
0564 ++i;
0565 if (normResidual < 1.5) {
0566 const DTRecHit1D& newHit1D = (*hit);
0567 updatedRecHits.push_back(newHit1D);
0568 if (debug)
0569 cout << " accepted " << i << "th hit"
0570 << " Irej: " << normResidual << endl;
0571 } else {
0572 if (debug)
0573 cout << " rejected " << i << "th hit"
0574 << " Irej: " << normResidual << endl;
0575 continue;
0576 }
0577 }
0578
0579 phiSeg->update(updatedRecHits);
0580
0581
0582 if (debug) {
0583 vector<float> x_upd;
0584 vector<float> y_upd;
0585
0586 cout << " Check the update action: " << endl;
0587
0588 vector<DTRecHit1D> hits_upd = phiSeg->specificRecHits();
0589 for (vector<DTRecHit1D>::const_iterator hit = hits_upd.begin(); hit != hits_upd.end(); ++hit) {
0590
0591 GlobalPoint glbPos = (theGeom->layer(hit->wireId().layerId()))->toGlobal(hit->localPosition());
0592 LocalPoint pos = (theGeom->idToDet(phiSeg->geographicalId()))->toLocal(glbPos);
0593
0594 x_upd.push_back(pos.z());
0595 y_upd.push_back(pos.x());
0596
0597 cout << " x_upd: " << pos.z() << " y_upd: " << pos.x() << endl;
0598 }
0599
0600 cout << " end of segment! " << endl;
0601 cout << " size = Number of Hits: " << x_upd.size() << " " << y_upd.size() << endl;
0602
0603 }
0604
0605 return;
0606 }
0607
0608 void DTSegmentUpdator::calculateT0corr(DTRecSegment4D* seg) const {
0609 if (seg->hasPhi())
0610 calculateT0corr(seg->phiSegment());
0611 if (seg->hasZed())
0612 calculateT0corr(seg->zSegment());
0613 }
0614
0615 void DTSegmentUpdator::calculateT0corr(DTRecSegment2D* seg) const {
0616
0617
0618 if (debug)
0619 cout << "[DTSegmentUpdator] CalculateT0corr DTRecSegment4D" << endl;
0620
0621 vector<double> d_drift;
0622 vector<float> x;
0623 vector<float> y;
0624 vector<int> lc;
0625
0626 vector<DTRecHit1D> hits = seg->specificRecHits();
0627
0628 DTWireId wireId;
0629 int nptfit = 0;
0630
0631 for (vector<DTRecHit1D>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
0632
0633 GlobalPoint glbPos = (theGeom->layer(hit->wireId().layerId()))->toGlobal(hit->localPosition());
0634 LocalPoint pos = (theGeom->idToDet(seg->geographicalId()))->toLocal(glbPos);
0635
0636 const DTLayer* layer = theGeom->layer(hit->wireId().layerId());
0637 float xwire = layer->specificTopology().wirePosition(hit->wireId().wire());
0638 float distance = fabs(hit->localPosition().x() - xwire);
0639
0640 int ilc = (hit->lrSide() == DTEnums::Left) ? 1 : -1;
0641
0642 nptfit++;
0643 x.push_back(pos.z());
0644 y.push_back(pos.x());
0645 lc.push_back(ilc);
0646 d_drift.push_back(distance);
0647
0648
0649 }
0650
0651 double chi2fit = 0.;
0652 float cminf = 0.;
0653 float vminf = 0.;
0654 float a, b;
0655
0656 if (nptfit > 2) {
0657
0658 theFitter->fit4Var(x, y, lc, d_drift, nptfit, a, b, cminf, vminf, chi2fit, vdrift_4parfit, debug);
0659
0660 double t0cor = -999.;
0661 if (cminf > -998.)
0662 t0cor = -cminf / 0.00543;
0663
0664
0665
0666
0667
0668
0669 seg->setT0(t0cor);
0670 seg->setVdrift(vminf);
0671 }
0672 }