File indexing completed on 2024-04-06 12:26:17
0001 #include "RecoLocalTracker/SiPhase2VectorHitBuilder/interface/VectorHitBuilderAlgorithm.h"
0002 #include "RecoLocalTracker/ClusterParameterEstimator/interface/ClusterParameterEstimator.h"
0003 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0004 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
0005 #include "DataFormats/TrackerRecHit2D/interface/VectorHit2D.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007
0008 void VectorHitBuilderAlgorithm::run(edm::Handle<edmNew::DetSetVector<Phase2TrackerCluster1D>> clusters,
0009 VectorHitCollection& vhAcc,
0010 VectorHitCollection& vhRej,
0011 edmNew::DetSetVector<Phase2TrackerCluster1D>& clustersAcc,
0012 edmNew::DetSetVector<Phase2TrackerCluster1D>& clustersRej) const {
0013 LogDebug("VectorHitBuilderAlgorithm") << "Run VectorHitBuilderAlgorithm ... \n";
0014 const auto* clustersPhase2Collection = clusters.product();
0015
0016
0017 LogDebug("VectorHitBuilderAlgorithm") << "with #clusters : " << clustersPhase2Collection->size() << std::endl;
0018 for (auto dSViter : *clustersPhase2Collection) {
0019 unsigned int rawDetId1(dSViter.detId());
0020 DetId detId1(rawDetId1);
0021 DetId lowerDetId, upperDetId;
0022 if (tkTopo_->isLower(detId1)) {
0023 lowerDetId = detId1;
0024 upperDetId = tkTopo_->partnerDetId(detId1);
0025 } else
0026 continue;
0027
0028 DetId detIdStack = tkTopo_->stack(detId1);
0029
0030
0031 LogDebug("VectorHitBuilderAlgorithm") << " DetId stack : " << detIdStack.rawId() << std::endl;
0032 LogDebug("VectorHitBuilderAlgorithm") << " DetId lower set of clusters : " << lowerDetId.rawId();
0033 LogDebug("VectorHitBuilderAlgorithm") << " DetId upper set of clusters : " << upperDetId.rawId() << std::endl;
0034
0035 const GeomDet* gd;
0036 const StackGeomDet* stackDet;
0037 const auto& it_detLower = dSViter;
0038 const auto& it_detUpper = clustersPhase2Collection->find(upperDetId);
0039
0040 if (it_detUpper != clustersPhase2Collection->end()) {
0041 gd = tkGeom_->idToDet(detIdStack);
0042 stackDet = dynamic_cast<const StackGeomDet*>(gd);
0043 buildVectorHits(vhAcc, vhRej, detIdStack, stackDet, clusters, it_detLower, *it_detUpper);
0044 }
0045 }
0046 LogDebug("VectorHitBuilderAlgorithm") << "End run VectorHitBuilderAlgorithm ... \n";
0047 }
0048
0049 bool VectorHitBuilderAlgorithm::checkClustersCompatibilityBeforeBuilding(
0050 edm::Handle<edmNew::DetSetVector<Phase2TrackerCluster1D>> clusters,
0051 const Detset& theLowerDetSet,
0052 const Detset& theUpperDetSet) const {
0053 if (theLowerDetSet.size() == 1 && theUpperDetSet.size() == 1)
0054 return true;
0055
0056
0057 std::vector<Phase2TrackerCluster1D> lowerClusters;
0058 lowerClusters.reserve(theLowerDetSet.size());
0059 if (theLowerDetSet.size() > 1)
0060 LogDebug("VectorHitBuilderAlgorithm") << " more than 1 lower cluster! " << std::endl;
0061 if (theUpperDetSet.size() > 1)
0062 LogDebug("VectorHitBuilderAlgorithm") << " more than 1 upper cluster! " << std::endl;
0063 for (const_iterator cil = theLowerDetSet.begin(); cil != theLowerDetSet.end(); ++cil) {
0064 Phase2TrackerCluster1DRef clusterLower = edmNew::makeRefTo(clusters, cil);
0065 lowerClusters.push_back(*clusterLower);
0066 }
0067 return true;
0068 }
0069
0070 bool VectorHitBuilderAlgorithm::checkClustersCompatibility(Local3DPoint& poslower,
0071 Local3DPoint& posupper,
0072 LocalError& errlower,
0073 LocalError& errupper) const {
0074 return true;
0075 }
0076
0077
0078
0079 void VectorHitBuilderAlgorithm::buildVectorHits(VectorHitCollection& vhAcc,
0080 VectorHitCollection& vhRej,
0081 DetId detIdStack,
0082 const StackGeomDet* stack,
0083 edm::Handle<edmNew::DetSetVector<Phase2TrackerCluster1D>> clusters,
0084 const Detset& theLowerDetSet,
0085 const Detset& theUpperDetSet,
0086 const std::vector<bool>& phase2OTClustersToSkip) const {
0087 if (checkClustersCompatibilityBeforeBuilding(clusters, theLowerDetSet, theUpperDetSet)) {
0088 LogDebug("VectorHitBuilderAlgorithm") << " compatible -> continue ... " << std::endl;
0089 } else {
0090 LogTrace("VectorHitBuilderAlgorithm") << " not compatible, going to the next cluster";
0091 }
0092
0093 edmNew::DetSetVector<VectorHit>::FastFiller vh_colAcc(vhAcc, detIdStack);
0094 edmNew::DetSetVector<VectorHit>::FastFiller vh_colRej(vhRej, detIdStack);
0095
0096 unsigned int layerStack = tkTopo_->layer(stack->geographicalId());
0097 if (stack->subDetector() == GeomDetEnumerators::SubDetector::P2OTB)
0098 LogDebug("VectorHitBuilderAlgorithm") << " \t is barrel. " << std::endl;
0099 if (stack->subDetector() == GeomDetEnumerators::SubDetector::P2OTEC)
0100 LogDebug("VectorHitBuilderAlgorithm") << " \t is endcap. " << std::endl;
0101 LogDebug("VectorHitBuilderAlgorithm") << " \t layer is : " << layerStack << std::endl;
0102
0103 float cut = 0.0;
0104 if (stack->subDetector() == GeomDetEnumerators::SubDetector::P2OTB)
0105 cut = barrelCut_.at(layerStack);
0106 if (stack->subDetector() == GeomDetEnumerators::SubDetector::P2OTEC)
0107 cut = endcapCut_.at(layerStack);
0108 LogDebug("VectorHitBuilderAlgorithm") << " \t the cut is:" << cut << std::endl;
0109
0110
0111 std::vector<std::pair<LocalPoint, LocalError>> localParamsUpper;
0112 std::vector<const PixelGeomDetUnit*> localGDUUpper;
0113
0114 const PixelGeomDetUnit* gduUpp = dynamic_cast<const PixelGeomDetUnit*>(stack->upperDet());
0115 for (auto const& clusterUpper : theUpperDetSet) {
0116 localGDUUpper.push_back(gduUpp);
0117 localParamsUpper.push_back(cpe_->localParameters(clusterUpper, *gduUpp));
0118 }
0119 int upperIterator = 0;
0120 const PixelGeomDetUnit* gduLow = dynamic_cast<const PixelGeomDetUnit*>(stack->lowerDet());
0121 for (const_iterator cil = theLowerDetSet.begin(); cil != theLowerDetSet.end(); ++cil) {
0122 LogDebug("VectorHitBuilderAlgorithm") << " lower clusters " << std::endl;
0123 Phase2TrackerCluster1DRef cluL = edmNew::makeRefTo(clusters, cil);
0124 #ifdef EDM_ML_DEBUG
0125 printCluster(stack->lowerDet(), &*cluL);
0126 #endif
0127 auto&& lparamsLow = cpe_->localParameters(*cluL, *gduLow);
0128 upperIterator = 0;
0129 for (const_iterator ciu = theUpperDetSet.begin(); ciu != theUpperDetSet.end(); ++ciu) {
0130 LogDebug("VectorHitBuilderAlgorithm") << "\t upper clusters " << std::endl;
0131 Phase2TrackerCluster1DRef cluU = edmNew::makeRefTo(clusters, ciu);
0132 #ifdef EDM_ML_DEBUG
0133 printCluster(stack->upperDet(), &*cluU);
0134 #endif
0135
0136 double pC = computeParallaxCorrection(
0137 gduLow, lparamsLow.first, localGDUUpper[upperIterator], localParamsUpper[upperIterator].first);
0138 LogDebug("VectorHitBuilderAlgorithm") << " \t parallax correction:" << pC << std::endl;
0139 double lpos_upp_corr = 0.0;
0140 double lpos_low_corr = 0.0;
0141 auto const localUpperX = localParamsUpper[upperIterator].first.x();
0142 if (localUpperX > lparamsLow.first.x()) {
0143 if (localUpperX > 0) {
0144 lpos_low_corr = lparamsLow.first.x();
0145 lpos_upp_corr = localParamsUpper[upperIterator].first.x() - std::abs(pC);
0146 } else if (localUpperX < 0) {
0147 lpos_low_corr = lparamsLow.first.x() + std::abs(pC);
0148 lpos_upp_corr = localUpperX;
0149 }
0150 } else if (localUpperX < lparamsLow.first.x()) {
0151 if (localUpperX > 0) {
0152 lpos_low_corr = lparamsLow.first.x() - std::abs(pC);
0153 lpos_upp_corr = localUpperX;
0154 } else if (localUpperX < 0) {
0155 lpos_low_corr = lparamsLow.first.x();
0156 lpos_upp_corr = localUpperX + std::abs(pC);
0157 }
0158 } else {
0159 if (localUpperX > 0) {
0160 lpos_low_corr = lparamsLow.first.x();
0161 lpos_upp_corr = localUpperX - std::abs(pC);
0162 } else if (localUpperX < 0) {
0163 lpos_low_corr = lparamsLow.first.x();
0164 lpos_upp_corr = localUpperX + std::abs(pC);
0165 }
0166 }
0167
0168 LogDebug("VectorHitBuilderAlgorithm") << " \t local pos upper corrected (x):" << lpos_upp_corr << std::endl;
0169 LogDebug("VectorHitBuilderAlgorithm") << " \t local pos lower corrected (x):" << lpos_low_corr << std::endl;
0170
0171 double width = lpos_low_corr - lpos_upp_corr;
0172 LogDebug("VectorHitBuilderAlgorithm") << " \t width: " << width << std::endl;
0173
0174
0175
0176
0177
0178
0179
0180
0181 if (std::abs(width) < cut) {
0182 LogDebug("VectorHitBuilderAlgorithm") << " accepting VH! " << std::endl;
0183 VectorHit vh = buildVectorHit(stack, cluL, cluU);
0184
0185 if (vh.isValid()) {
0186 vh_colAcc.push_back(vh);
0187 }
0188
0189 } else {
0190 LogDebug("VectorHitBuilderAlgorithm") << " rejecting VH: " << std::endl;
0191
0192 VectorHit vh = buildVectorHit(stack, cluL, cluU);
0193 if (vh.isValid()) {
0194 vh_colRej.push_back(vh);
0195 }
0196 }
0197 upperIterator += 1;
0198 }
0199 }
0200 }
0201
0202 VectorHit VectorHitBuilderAlgorithm::buildVectorHit(const StackGeomDet* stack,
0203 Phase2TrackerCluster1DRef lower,
0204 Phase2TrackerCluster1DRef upper) const {
0205 LogTrace("VectorHitBuilderAlgorithm") << "Build VH with: ";
0206 #ifdef EDM_ML_DEBUG
0207 printCluster(stack->upperDet(), &*upper);
0208 #endif
0209 const PixelGeomDetUnit* geomDetLower = static_cast<const PixelGeomDetUnit*>(stack->lowerDet());
0210 const PixelGeomDetUnit* geomDetUpper = static_cast<const PixelGeomDetUnit*>(stack->upperDet());
0211
0212 auto&& lparamsLower = cpe_->localParameters(*lower, *geomDetLower);
0213 Global3DPoint gparamsLower = geomDetLower->surface().toGlobal(lparamsLower.first);
0214 LogTrace("VectorHitBuilderAlgorithm") << "\t lower global pos: " << gparamsLower;
0215
0216 auto&& lparamsUpper = cpe_->localParameters(*upper, *geomDetUpper);
0217 Global3DPoint gparamsUpper = geomDetUpper->surface().toGlobal(lparamsUpper.first);
0218 LogTrace("VectorHitBuilderAlgorithm") << "\t upper global pos: " << gparamsUpper;
0219
0220
0221 Local3DPoint lparamsUpperInLower = geomDetLower->surface().toLocal(gparamsUpper);
0222
0223 LogTrace("VectorHitBuilderAlgorithm") << "\t lower global pos: " << gparamsLower;
0224 LogTrace("VectorHitBuilderAlgorithm") << "\t upper global pos: " << gparamsUpper;
0225
0226 LogTrace("VectorHitBuilderAlgorithm") << "A:\t lower local pos: " << lparamsLower.first
0227 << " with error: " << lparamsLower.second << std::endl;
0228 LogTrace("VectorHitBuilderAlgorithm") << "A:\t upper local pos in the lower sof " << lparamsUpperInLower
0229 << " with error: " << lparamsUpper.second << std::endl;
0230
0231 bool ok =
0232 checkClustersCompatibility(lparamsLower.first, lparamsUpper.first, lparamsLower.second, lparamsUpper.second);
0233
0234 if (ok) {
0235 AlgebraicSymMatrix22 covMat2Dzx;
0236 double chi22Dzx = 0.0;
0237 Local3DPoint pos2Dzx;
0238 Local3DVector dir2Dzx;
0239 fit2Dzx(lparamsLower.first,
0240 lparamsUpperInLower,
0241 lparamsLower.second,
0242 lparamsUpper.second,
0243 pos2Dzx,
0244 dir2Dzx,
0245 covMat2Dzx,
0246 chi22Dzx);
0247 LogTrace("VectorHitBuilderAlgorithm") << "\t pos2Dzx: " << pos2Dzx;
0248 LogTrace("VectorHitBuilderAlgorithm") << "\t dir2Dzx: " << dir2Dzx;
0249 LogTrace("VectorHitBuilderAlgorithm") << "\t cov2Dzx: " << covMat2Dzx;
0250 VectorHit2D vh2Dzx = VectorHit2D(pos2Dzx, dir2Dzx, covMat2Dzx, chi22Dzx);
0251
0252 AlgebraicSymMatrix22 covMat2Dzy;
0253 double chi22Dzy = 0.0;
0254 Local3DPoint pos2Dzy;
0255 Local3DVector dir2Dzy;
0256 fit2Dzy(lparamsLower.first,
0257 lparamsUpperInLower,
0258 lparamsLower.second,
0259 lparamsUpper.second,
0260 pos2Dzy,
0261 dir2Dzy,
0262 covMat2Dzy,
0263 chi22Dzy);
0264 LogTrace("VectorHitBuilderAlgorithm") << "\t pos2Dzy: " << pos2Dzy;
0265 LogTrace("VectorHitBuilderAlgorithm") << "\t dir2Dzy: " << dir2Dzy;
0266 LogTrace("VectorHitBuilderAlgorithm") << "\t cov2Dzy: " << covMat2Dzy;
0267 VectorHit2D vh2Dzy = VectorHit2D(pos2Dzy, dir2Dzy, covMat2Dzy, chi22Dzy);
0268
0269 OmniClusterRef lowerOmni(lower);
0270 OmniClusterRef upperOmni(upper);
0271
0272 Global3DPoint gPositionLower = VectorHit::phase2clusterGlobalPos(geomDetLower, lower);
0273 Global3DPoint gPositionUpper = VectorHit::phase2clusterGlobalPos(geomDetUpper, upper);
0274 GlobalError gErrorLower = VectorHit::phase2clusterGlobalPosErr(geomDetLower);
0275 GlobalError gErrorUpper = VectorHit::phase2clusterGlobalPosErr(geomDetUpper);
0276
0277 if (gPositionLower.perp() > gPositionUpper.perp()) {
0278 std::swap(gPositionLower, gPositionUpper);
0279 std::swap(gErrorLower, gErrorUpper);
0280 }
0281
0282 const CurvatureAndPhi curvatureAndPhi = curvatureANDphi(gPositionLower, gPositionUpper, gErrorLower, gErrorUpper);
0283 VectorHit vh = VectorHit(*stack,
0284 vh2Dzx,
0285 vh2Dzy,
0286 lowerOmni,
0287 upperOmni,
0288 curvatureAndPhi.curvature,
0289 curvatureAndPhi.curvatureError,
0290 curvatureAndPhi.phi);
0291 return vh;
0292 }
0293
0294 return VectorHit();
0295 }
0296
0297 void VectorHitBuilderAlgorithm::fit2Dzx(const Local3DPoint lpCI,
0298 const Local3DPoint lpCO,
0299 const LocalError leCI,
0300 const LocalError leCO,
0301 Local3DPoint& pos,
0302 Local3DVector& dir,
0303 AlgebraicSymMatrix22& covMatrix,
0304 double& chi2) const {
0305 float x[2] = {lpCI.z(), lpCO.z()};
0306 float y[2] = {lpCI.x(), lpCO.x()};
0307 float sqCI = sqrt(leCI.xx());
0308 float sqCO = sqrt(leCO.xx());
0309 float sigy2[2] = {sqCI * sqCI, sqCO * sqCO};
0310
0311 fit(x, y, sigy2, pos, dir, covMatrix, chi2);
0312
0313 return;
0314 }
0315
0316 void VectorHitBuilderAlgorithm::fit2Dzy(const Local3DPoint lpCI,
0317 const Local3DPoint lpCO,
0318 const LocalError leCI,
0319 const LocalError leCO,
0320 Local3DPoint& pos,
0321 Local3DVector& dir,
0322 AlgebraicSymMatrix22& covMatrix,
0323 double& chi2) const {
0324 float x[2] = {lpCI.z(), lpCO.z()};
0325 float y[2] = {lpCI.y(), lpCO.y()};
0326 float sqCI = sqrt(leCI.yy());
0327 float sqCO = sqrt(leCO.yy());
0328 float sigy2[2] = {sqCI * sqCI, sqCO * sqCO};
0329
0330 fit(x, y, sigy2, pos, dir, covMatrix, chi2);
0331
0332 return;
0333 }
0334
0335 void VectorHitBuilderAlgorithm::fit(float x[2],
0336 float y[2],
0337 float sigy2[2],
0338 Local3DPoint& pos,
0339 Local3DVector& dir,
0340 AlgebraicSymMatrix22& covMatrix,
0341 double& chi2) const {
0342 float slope = 0.;
0343 float intercept = 0.;
0344 float covss = 0.;
0345 float covii = 0.;
0346 float covsi = 0.;
0347
0348 linearFit(x, y, 2, sigy2, slope, intercept, covss, covii, covsi);
0349
0350 covMatrix[0][0] = covss;
0351 covMatrix[1][1] = covii;
0352 covMatrix[1][0] = covsi;
0353
0354 for (unsigned int j = 0; j < 2; j++) {
0355 const double ypred = intercept + slope * x[j];
0356 const double dy = (y[j] - ypred) / sqrt(sigy2[j]);
0357 chi2 += dy * dy;
0358 }
0359
0360 pos = Local3DPoint(intercept, 0., 0.);
0361
0362 float slopeZ = x[1] - x[0];
0363 dir = LocalVector(slope, 0., slopeZ);
0364 }
0365
0366 VectorHitBuilderAlgorithm::CurvatureAndPhi VectorHitBuilderAlgorithm::curvatureANDphi(Global3DPoint gPositionLower,
0367 Global3DPoint gPositionUpper,
0368 GlobalError gErrorLower,
0369 GlobalError gErrorUpper) const {
0370 VectorHitBuilderAlgorithm::CurvatureAndPhi result;
0371
0372 float curvature = -999.;
0373 float errorCurvature = -999.;
0374 float phi = -999.;
0375
0376 float h1 = gPositionLower.x() * gPositionUpper.y() - gPositionUpper.x() * gPositionLower.y();
0377
0378
0379 AlgebraicVector2 n1;
0380 n1[0] = -gPositionLower.y();
0381 n1[1] = gPositionLower.x();
0382 AlgebraicVector2 n2;
0383 n2[0] = gPositionUpper.x() - gPositionLower.x();
0384 n2[1] = gPositionUpper.y() - gPositionLower.y();
0385
0386 double n3 = n1[0] * n2[0] + n1[1] * n2[1];
0387 double signCurv = -copysign(1.0, n3);
0388 double phi1 = atan2(gPositionUpper.y() - gPositionLower.y(), gPositionUpper.x() - gPositionLower.x());
0389
0390 double x2Low = pow(gPositionLower.x(), 2);
0391 double y2Low = pow(gPositionLower.y(), 2);
0392 double x2Up = pow(gPositionUpper.x(), 2);
0393 double y2Up = pow(gPositionUpper.y(), 2);
0394
0395 if (h1 != 0) {
0396 double h2 = 2 * h1;
0397 double h2Inf = 1. / (2 * h1);
0398 double r12 = gPositionLower.perp2();
0399 double r22 = gPositionUpper.perp2();
0400 double h3 = pow(n2[0], 2) + pow(n2[1], 2);
0401 double h4 = -x2Low * gPositionUpper.x() + gPositionLower.x() * x2Up + gPositionLower.x() * y2Up -
0402 gPositionUpper.x() * y2Low;
0403 double h5 =
0404 x2Low * gPositionUpper.y() - x2Up * gPositionLower.y() + y2Low * gPositionUpper.y() - gPositionLower.y() * y2Up;
0405
0406
0407 double invRho2 = (4. * h1 * h1) / (r12 * r22 * h3);
0408 curvature = sqrt(invRho2);
0409
0410
0411 double xcentre = h5 / h2;
0412 double ycentre = h4 / h2;
0413
0414
0415 double xtg = gPositionLower.y() - ycentre;
0416 double ytg = -(gPositionLower.x() - xcentre);
0417
0418
0419 phi = atan2(ytg, xtg);
0420
0421 AlgebraicROOTObject<4, 4>::Matrix jacobian;
0422
0423 double denom1 = 1. / sqrt(r12 * r22 * h3);
0424 double denom2 = 1. / (pow(r12 * r22 * h3, 1.5));
0425 jacobian[0][0] = 1.0;
0426 jacobian[1][1] = 1.0;
0427 jacobian[2][0] =
0428 -2. * ((h1 * (gPositionLower.x() * r22 * h3 + (gPositionLower.x() - gPositionUpper.x()) * r12 * r22)) * denom2 -
0429 (gPositionUpper.y()) * denom1);
0430 jacobian[2][1] =
0431 -2. * ((gPositionUpper.x()) * denom1 +
0432 (h1 * (gPositionLower.y() * r22 * h3 + r12 * r22 * (gPositionLower.y() - gPositionUpper.y()))) *
0433 denom2);
0434 jacobian[2][2] =
0435 -2. * ((gPositionLower.y()) * denom1 +
0436 (h1 * (gPositionUpper.x() * r12 * h3 - (gPositionLower.x() - gPositionUpper.x()) * r12 * r22)) *
0437 denom2);
0438 jacobian[2][3] =
0439 -2. * ((h1 * (gPositionUpper.y() * r12 * h3 - r12 * r22 * (gPositionLower.y() - gPositionUpper.y()))) * denom2 -
0440 (gPositionLower.x()) * denom1);
0441 AlgebraicVector2 mVector;
0442
0443 mVector[0] = (gPositionLower.y() - ycentre) * invRho2;
0444 mVector[1] = -(gPositionLower.x() - xcentre) * invRho2;
0445
0446
0447 double h22Inv = 1. / pow(h2, 2);
0448
0449 AlgebraicROOTObject<2, 4>::Matrix kMatrix;
0450 kMatrix[0][0] =
0451 2. * ((gPositionLower.x() * gPositionUpper.y()) * h2Inf - (gPositionUpper.y() * h5) * h22Inv);
0452 kMatrix[0][1] = (2. * gPositionUpper.x() * h5) * h22Inv -
0453 (x2Up + y2Up - 2. * gPositionLower.y() * gPositionUpper.y()) * h2Inf;
0454 kMatrix[0][2] =
0455 2. * ((gPositionLower.y() * h5) * h22Inv - (gPositionUpper.x() * gPositionLower.y()) * h2Inf);
0456 kMatrix[0][3] = (x2Low + y2Low - 2. * gPositionUpper.y() * gPositionLower.y()) * h2Inf -
0457 (2. * gPositionLower.x() * h5) * h22Inv;
0458 kMatrix[1][0] = (x2Up - 2. * gPositionLower.x() * gPositionUpper.x() + y2Up) * h2Inf -
0459 (2. * gPositionUpper.y() * h4) * h22Inv;
0460 kMatrix[1][1] =
0461 2. * ((gPositionUpper.x() * h4) * h22Inv - (gPositionUpper.x() * gPositionLower.y()) * h2Inf);
0462 kMatrix[1][2] = (2. * gPositionLower.y() * h4) * h22Inv -
0463 (x2Low - 2. * gPositionUpper.x() * gPositionLower.x() + y2Low) * h2Inf;
0464 kMatrix[1][3] =
0465 2. * (gPositionLower.x() * gPositionUpper.y()) * h2Inf - (gPositionLower.x() * h4) * h22Inv;
0466
0467 AlgebraicVector4 nMatrix = mVector * kMatrix;
0468 jacobian[3][0] = nMatrix[0];
0469 jacobian[3][1] = nMatrix[1];
0470 jacobian[3][2] = nMatrix[2];
0471 jacobian[3][3] = nMatrix[3];
0472
0473
0474 if ((signCurv < 0 && curvature > 0) || (signCurv > 0 && curvature < 0)) {
0475 curvature = -curvature;
0476 for (int i = 0; i < 4; i++) {
0477 jacobian[2][i] = -jacobian[2][i];
0478 }
0479 }
0480
0481
0482 if (deltaPhi(phi, phi1) > M_PI / 2.) {
0483 phi = phi + M_PI;
0484 if (phi > M_PI)
0485 phi = phi - 2. * M_PI;
0486 }
0487
0488
0489 AlgebraicVector4 curvatureJacobian;
0490 for (int i = 0; i < 4; i++) {
0491 curvatureJacobian[i] = jacobian[2][i];
0492 }
0493
0494 AlgebraicROOTObject<4, 4>::Matrix gErrors;
0495
0496 gErrors[0][0] = gErrorLower.cxx();
0497 gErrors[0][1] = gErrorLower.cyx();
0498 gErrors[1][0] = gErrorLower.cyx();
0499 gErrors[1][1] = gErrorLower.cyy();
0500 gErrors[2][2] = gErrorUpper.cxx();
0501 gErrors[2][3] = gErrorUpper.cyx();
0502 gErrors[3][2] = gErrorUpper.cyx();
0503 gErrors[3][3] = gErrorUpper.cyy();
0504
0505 AlgebraicVector4 temp = curvatureJacobian;
0506 temp = temp * gErrors;
0507 errorCurvature = temp[0] * curvatureJacobian[0] + temp[1] * curvatureJacobian[1] + temp[2] * curvatureJacobian[2] +
0508 temp[3] * curvatureJacobian[3];
0509 }
0510
0511 result.curvature = curvature;
0512 result.curvatureError = errorCurvature;
0513 result.phi = phi;
0514 return result;
0515 }