File indexing completed on 2024-04-06 12:28:01
0001 #include "HitQuadrupletGeneratorFromLayerPairForPhotonConversion.h"
0002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0003
0004 #include "TrackingTools/DetLayers/interface/DetLayer.h"
0005 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
0006 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
0007
0008 #include "RecoTracker/TkTrackingRegions/interface/HitRZCompatibility.h"
0009 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegion.h"
0010 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegionBase.h"
0011 #include "RecoTracker/TkHitPairs/interface/OrderedHitPairs.h"
0012
0013 using namespace GeomDetEnumerators;
0014 using namespace std;
0015 #include "RecoTracker/TkMSParametrization/interface/PixelRecoUtilities.h"
0016
0017
0018
0019 typedef PixelRecoRange<float> Range;
0020 template <class T>
0021 inline T sqr(T t) {
0022 return t * t;
0023 }
0024
0025 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h"
0026 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
0027 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0028 #include "RecoTracker/Record/interface/TrackerRecoGeometryRecord.h"
0029 #include "FWCore/Framework/interface/ESHandle.h"
0030 #include "DataFormats/Math/interface/deltaPhi.h"
0031
0032 HitQuadrupletGeneratorFromLayerPairForPhotonConversion::HitQuadrupletGeneratorFromLayerPairForPhotonConversion(
0033 unsigned int inner, unsigned int outer, LayerCacheType *layerCache, unsigned int max)
0034 : theLayerCache(*layerCache), theOuterLayer(outer), theInnerLayer(inner), theMaxElement(max) {
0035 ss = new std::stringstream;
0036 }
0037
0038 void HitQuadrupletGeneratorFromLayerPairForPhotonConversion::hitPairs(const TrackingRegion ®ion,
0039 OrderedHitPairs &result,
0040 const Layers &layers) {
0041 ss->str("");
0042
0043 typedef OrderedHitPair::InnerRecHit InnerHit;
0044 typedef OrderedHitPair::OuterRecHit OuterHit;
0045 typedef RecHitsSortedInPhi::Hit Hit;
0046
0047 Layer innerLayerObj = layers[theInnerLayer];
0048 Layer outerLayerObj = layers[theOuterLayer];
0049
0050 #ifdef mydebug_QSeed
0051 size_t totCountP2 = 0, totCountP1 = 0, totCountM2 = 0, totCountM1 = 0, selCount = 0;
0052 (*ss) << "In " << innerLayerObj.name() << " Out " << theOuterLayer.name() << std::endl;
0053 #endif
0054
0055
0056 const RecHitsSortedInPhi &innerHitsMap = theLayerCache(innerLayerObj, region);
0057 if (innerHitsMap.empty())
0058 return;
0059
0060 const RecHitsSortedInPhi &outerHitsMap = theLayerCache(outerLayerObj, region);
0061 if (outerHitsMap.empty())
0062 return;
0063
0064
0065
0066
0067
0068 vector<RecHitsSortedInPhi::Hit> innerHits;
0069
0070 float innerPhimin, innerPhimax;
0071 float maxDeltaPhi = 1.;
0072
0073
0074 RecHitsSortedInPhi::Range outerHits = outerHitsMap.all();
0075
0076 RecHitsSortedInPhi::HitIter nextoh;
0077 for (RecHitsSortedInPhi::HitIter oh = outerHits.first; oh != outerHits.second; ++oh) {
0078 RecHitsSortedInPhi::Hit ohit = (*oh).hit();
0079 GlobalPoint oPos = ohit->globalPosition();
0080
0081 #ifdef mydebug_QSeed
0082 totCountP2++;
0083 #endif
0084 std::unique_ptr<const HitRZCompatibility> checkRZ = region.checkRZ(outerLayerObj.detLayer(), ohit);
0085 for (nextoh = oh + 1; nextoh != outerHits.second; ++nextoh) {
0086 RecHitsSortedInPhi::Hit nohit = (*nextoh).hit();
0087 GlobalPoint noPos = nohit->globalPosition();
0088
0089 #ifdef mydebug_QSeed
0090 (*ss) << "\toPos " << oPos << " r " << oPos.perp() << " phi " << oPos.phi() << " cotTheta "
0091 << oPos.z() / oPos.perp() << std::endl;
0092 (*ss) << "\tnoPos " << noPos << " r " << noPos.perp() << " phi " << noPos.phi() << " cotTheta "
0093 << noPos.z() / noPos.perp() << std::endl;
0094 (*ss) << "\tDeltaPhi " << reco::deltaPhi(noPos.barePhi(), oPos.barePhi()) << std::endl;
0095 #endif
0096
0097 if (fabs(reco::deltaPhi(noPos.barePhi(), oPos.barePhi())) > maxDeltaPhi)
0098 break;
0099
0100 #ifdef mydebug_QSeed
0101 totCountM2++;
0102 #endif
0103
0104
0105 if (failCheckRZCompatibility(nohit, *outerLayerObj.detLayer(), checkRZ.get(), region))
0106 continue;
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 innerPhimin = ohit->globalPosition().phi();
0118 innerPhimax = nohit->globalPosition().phi();
0119
0120
0121 innerHits.clear();
0122 innerHitsMap.hits(innerPhimin, innerPhimax, innerHits);
0123
0124 #ifdef mydebug_QSeed
0125 (*ss) << "\tiphimin, iphimax " << innerPhimin << " " << innerPhimax << std::endl;
0126 #endif
0127
0128 std::unique_ptr<const HitRZCompatibility> checkRZb = region.checkRZ(innerLayerObj.detLayer(), ohit);
0129 std::unique_ptr<const HitRZCompatibility> checkRZc = region.checkRZ(innerLayerObj.detLayer(), nohit);
0130
0131
0132 vector<RecHitsSortedInPhi::Hit>::const_iterator ieh = innerHits.end();
0133 for (vector<RecHitsSortedInPhi::Hit>::const_iterator ih = innerHits.begin(); ih < ieh; ++ih) {
0134 RecHitsSortedInPhi::Hit ihit = *ih;
0135
0136 #ifdef mydebug_QSeed
0137 GlobalPoint innPos = (*ih)->globalPosition();
0138 (*ss) << "\toPos " << oPos << " r " << oPos.perp() << " phi " << oPos.phi() << " cotTheta "
0139 << oPos.z() / oPos.perp() << std::endl;
0140 (*ss) << "\tnoPos " << noPos << " r " << noPos.perp() << " phi " << noPos.phi() << " cotTheta "
0141 << noPos.z() / noPos.perp() << std::endl;
0142 (*ss) << "\tinnPos " << innPos << " r " << innPos.perp() << " phi " << innPos.phi() << " cotTheta "
0143 << innPos.z() / innPos.perp() << std::endl;
0144
0145 totCountP1++;
0146 #endif
0147
0148 if (failCheckRZCompatibility(ihit, *innerLayerObj.detLayer(), checkRZb.get(), region) ||
0149 failCheckRZCompatibility(ihit, *innerLayerObj.detLayer(), checkRZc.get(), region))
0150 continue;
0151
0152 for (vector<RecHitsSortedInPhi::Hit>::const_iterator nextih = ih + 1; nextih != ieh; ++nextih) {
0153 RecHitsSortedInPhi::Hit nihit = *nextih;
0154
0155 #ifdef mydebug_QSeed
0156 GlobalPoint ninnPos = (*nextih)->globalPosition();
0157 (*ss) << "\toPos " << oPos << " r " << oPos.perp() << " phi " << oPos.phi() << " cotTheta "
0158 << oPos.z() / oPos.perp() << std::endl;
0159 (*ss) << "\tnoPos " << noPos << " r " << noPos.perp() << " phi " << noPos.phi() << " cotTheta "
0160 << noPos.z() / noPos.perp() << std::endl;
0161 (*ss) << "\tinnPos " << innPos << " r " << innPos.perp() << " phi " << innPos.phi() << " cotTheta "
0162 << innPos.z() / innPos.perp() << std::endl;
0163 (*ss) << "\tninnPos " << ninnPos << " r " << ninnPos.perp() << " phi " << ninnPos.phi() << " cotTheta "
0164 << ninnPos.z() / ninnPos.perp() << std::endl;
0165
0166 totCountM1++;
0167 #endif
0168
0169
0170 if (failCheckRZCompatibility(nihit, *innerLayerObj.detLayer(), checkRZb.get(), region) ||
0171 failCheckRZCompatibility(nihit, *innerLayerObj.detLayer(), checkRZc.get(), region))
0172 continue;
0173
0174
0175 if (failCheckSlopeTest(ohit, nohit, ihit, nihit, region))
0176 continue;
0177
0178 if (theMaxElement != 0 && result.size() >= theMaxElement) {
0179 result.clear();
0180 edm::LogError("TooManyQuads") << "number of Quad combinations exceed maximum, no quads produced";
0181 #ifdef mydebug_QSeed
0182 (*ss) << "In " << innerLayerObj.name() << " Out " << outerLayerObj.name() << "\tP2 " << totCountP2
0183 << "\tM2 " << totCountM2 << "\tP1 " << totCountP1 << "\tM1 " << totCountM1 << "\tsel " << selCount
0184 << std::endl;
0185 std::cout << (*ss).str();
0186 #endif
0187 return;
0188 }
0189 #ifdef mydebug_QSeed
0190 selCount++;
0191 #endif
0192 result.push_back(OrderedHitPair(ihit, ohit));
0193 result.push_back(OrderedHitPair(nihit, nohit));
0194
0195
0196
0197 }
0198 }
0199 }
0200 }
0201 #ifdef mydebug_QSeed
0202 (*ss) << "In " << innerLayerObj.name() << " Out " << outerLayerObj.name() << "\tP2 " << totCountP2 << "\tM2 "
0203 << totCountM2 << "\tP1 " << totCountP1 << "\tM1 " << totCountM1 << "\tsel " << selCount << std::endl;
0204 std::cout << (*ss).str();
0205 #endif
0206 }
0207
0208 bool HitQuadrupletGeneratorFromLayerPairForPhotonConversion::failCheckRZCompatibility(const RecHitsSortedInPhi::Hit &hit,
0209 const DetLayer &layer,
0210 const HitRZCompatibility *checkRZ,
0211 const TrackingRegion ®ion) {
0212 if (!checkRZ) {
0213 #ifdef mydebug_QSeed
0214 (*ss) << "*******\nNo valid checkRZ\n*******" << std::endl;
0215 #endif
0216 return true;
0217 }
0218
0219 static const float nSigmaRZ = std::sqrt(12.f);
0220 float r_reduced = std::sqrt(sqr(hit->globalPosition().x() - region.origin().x()) +
0221 sqr(hit->globalPosition().y() - region.origin().y()));
0222 Range allowed;
0223 Range hitRZ;
0224 if (layer.location() == barrel) {
0225 allowed = checkRZ->range(r_reduced);
0226 float zErr = nSigmaRZ * hit->errorGlobalZ();
0227 hitRZ = Range(hit->globalPosition().z() - zErr, hit->globalPosition().z() + zErr);
0228 } else {
0229 allowed = checkRZ->range(hit->globalPosition().z());
0230 float rErr = nSigmaRZ * hit->errorGlobalR();
0231 hitRZ = Range(r_reduced - rErr, r_reduced + rErr);
0232 }
0233 Range crossRange = allowed.intersection(hitRZ);
0234
0235 #ifdef mydebug_QSeed
0236 (*ss) << "\n\t\t allowed Range " << allowed.min() << " \t, " << allowed.max() << "\n\t\t hitRz Range "
0237 << hitRZ.min() << " \t, " << hitRZ.max() << "\n\t\t Cross Range " << crossRange.min() << " \t, "
0238 << crossRange.max() << std::endl;
0239 if (!crossRange.empty())
0240 (*ss) << "\n\t\t !!!!ACCEPTED!!! \n\n";
0241 #endif
0242
0243 return crossRange.empty();
0244 }
0245
0246 bool HitQuadrupletGeneratorFromLayerPairForPhotonConversion::failCheckSlopeTest(const RecHitsSortedInPhi::Hit &ohit,
0247 const RecHitsSortedInPhi::Hit &nohit,
0248 const RecHitsSortedInPhi::Hit &ihit,
0249 const RecHitsSortedInPhi::Hit &nihit,
0250 const TrackingRegion ®ion) {
0251 double r[5], z[5], ez[5];
0252
0253
0254
0255
0256 r[0] = ohit->globalPosition().perp();
0257 z[0] = ohit->globalPosition().z();
0258 ez[0] = getEffectiveErrorOnZ(ohit, region);
0259
0260 r[1] = nohit->globalPosition().perp();
0261 z[1] = nohit->globalPosition().z();
0262 ez[1] = getEffectiveErrorOnZ(nohit, region);
0263
0264 r[2] = nihit->globalPosition().perp();
0265 z[2] = nihit->globalPosition().z();
0266 ez[2] = getEffectiveErrorOnZ(nihit, region);
0267
0268 r[3] = ihit->globalPosition().perp();
0269 z[3] = ihit->globalPosition().z();
0270 ez[3] = getEffectiveErrorOnZ(ihit, region);
0271
0272
0273 bubbleSortVsR(4, r, z, ez);
0274
0275
0276 r[4] = region.origin().perp();
0277 z[4] = region.origin().z();
0278 double vError = region.originZBound();
0279 if (vError > 15.)
0280 vError = 1.;
0281 ez[4] = 3. * vError;
0282
0283
0284
0285
0286
0287 double rInn = r[4];
0288 double zInnMin = z[4] - ez[4];
0289 double zInnMax = z[4] + ez[4];
0290
0291
0292 double rOut = r[3];
0293 double zOutMin = z[3] - ez[3];
0294 double zOutMax = z[3] + ez[3];
0295 double rInt = r[2];
0296 double zIntMin = z[2] - ez[2];
0297 double zIntMax = z[2] + ez[2];
0298 if (failCheckSegmentZCompatibility(rInn, zInnMin, zInnMax, rInt, zIntMin, zIntMax, rOut, zOutMin, zOutMax))
0299 return true;
0300
0301
0302 rOut = rInt;
0303 zOutMin = zIntMin;
0304 zOutMax = zIntMax;
0305 rInt = r[1];
0306 zIntMin = z[1] - ez[1];
0307 zIntMax = z[1] + ez[1];
0308 if (failCheckSegmentZCompatibility(rInn, zInnMin, zInnMax, rInt, zIntMin, zIntMax, rOut, zOutMin, zOutMax))
0309 return true;
0310
0311
0312 rOut = rInt;
0313 zOutMin = zIntMin;
0314 zOutMax = zIntMax;
0315 rInt = r[0];
0316 zIntMin = z[0] - ez[0];
0317 zIntMax = z[0] + ez[0];
0318 if (failCheckSegmentZCompatibility(rInn, zInnMin, zInnMax, rInt, zIntMin, zIntMax, rOut, zOutMin, zOutMax))
0319 return true;
0320
0321
0322
0323 return false;
0324 }
0325
0326 double HitQuadrupletGeneratorFromLayerPairForPhotonConversion::verySimpleFit(
0327 int size, double *ax, double *ay, double *e2y, double &p0, double &e2p0, double &p1) {
0328
0329 return 0;
0330 }
0331
0332 double HitQuadrupletGeneratorFromLayerPairForPhotonConversion::getSqrEffectiveErrorOnZ(
0333 const RecHitsSortedInPhi::Hit &hit, const TrackingRegion ®ion) {
0334
0335
0336
0337
0338 double sqrProjFactor =
0339 sqr((hit->globalPosition().z() - region.origin().z()) / (hit->globalPosition().perp() - region.origin().perp()));
0340 return (hit->globalPositionError().czz() + sqrProjFactor * hit->globalPositionError().rerr(hit->globalPosition()));
0341 }
0342
0343 double HitQuadrupletGeneratorFromLayerPairForPhotonConversion::getEffectiveErrorOnZ(const RecHitsSortedInPhi::Hit &hit,
0344 const TrackingRegion ®ion) {
0345
0346
0347
0348 double sqrProjFactor =
0349 sqr((hit->globalPosition().z() - region.origin().z()) / (hit->globalPosition().perp() - region.origin().perp()));
0350 double effErr =
0351 sqrt(hit->globalPositionError().czz() + sqrProjFactor * hit->globalPositionError().rerr(hit->globalPosition()));
0352 if (effErr > 2.) {
0353 effErr *= 1.8;
0354
0355
0356
0357 } else {
0358 effErr *= 2.;
0359
0360 }
0361 return effErr;
0362 }
0363
0364 void HitQuadrupletGeneratorFromLayerPairForPhotonConversion::bubbleSortVsR(int n, double *ar, double *az, double *aez) {
0365 bool swapped = true;
0366 int j = 0;
0367 double tmpr, tmpz, tmpez;
0368 while (swapped) {
0369 swapped = false;
0370 j++;
0371 for (int i = 0; i < n - j; i++) {
0372 if (ar[i] > ar[i + 1]) {
0373 tmpr = ar[i];
0374 ar[i] = ar[i + 1];
0375 ar[i + 1] = tmpr;
0376 tmpz = az[i];
0377 az[i] = az[i + 1];
0378 az[i + 1] = tmpz;
0379 tmpez = aez[i];
0380 aez[i] = aez[i + 1];
0381 aez[i + 1] = tmpez;
0382 swapped = true;
0383 }
0384 }
0385 }
0386 }
0387
0388 bool HitQuadrupletGeneratorFromLayerPairForPhotonConversion::failCheckSegmentZCompatibility(double &rInn,
0389 double &zInnMin,
0390 double &zInnMax,
0391 double &rInt,
0392 double &zIntMin,
0393 double &zIntMax,
0394 double &rOut,
0395 double &zOutMin,
0396 double &zOutMax) {
0397
0398
0399
0400
0401
0402 double zLeft = getZAtR(rInn, zInnMin, rInt, rOut, zOutMin);
0403 if (zIntMax < zLeft)
0404 return true;
0405
0406 double zRight = getZAtR(rInn, zInnMax, rInt, rOut, zOutMax);
0407 if (zIntMin > zRight)
0408 return true;
0409 if (zIntMin < zLeft && zIntMax < zRight) {
0410 zIntMax = zLeft;
0411 return false;
0412 }
0413 if (zIntMin > zLeft && zIntMax > zRight) {
0414 zIntMax = zRight;
0415 return false;
0416 }
0417
0418
0419 return false;
0420 }
0421
0422 double HitQuadrupletGeneratorFromLayerPairForPhotonConversion::getZAtR(
0423 double &rInn, double &zInn, double &r, double &rOut, double &zOut) {
0424
0425
0426
0427
0428 return zInn + (zOut - zInn) * (r - rInn) / (rOut - rInn);
0429 }