diff --git a/InnerDetector/InDetExample/InDetRecExample/python/ConfiguredNewTrackingCuts.py b/InnerDetector/InDetExample/InDetRecExample/python/ConfiguredNewTrackingCuts.py index 4d43e2d36b436b4b573206c597a5ebe5236e02b7..0a6d159e0a47e5e5b40b49d0ecf10531c4b59cef 100755 --- a/InnerDetector/InDetExample/InDetRecExample/python/ConfiguredNewTrackingCuts.py +++ b/InnerDetector/InDetExample/InDetRecExample/python/ConfiguredNewTrackingCuts.py @@ -229,6 +229,7 @@ class ConfiguredNewTrackingCuts : # Designed to speed up reconstruction at minimal performance impact. self.__roadWidth = 12 self.__maxdImpactSSSSeeds = 5.0 * Units.mm + self.__maxZImpact = 200 if self.__indetflags.cutLevel() >= 18: # Further tuning of the pattern recognition designed to diff --git a/InnerDetector/InDetExample/InDetRecExample/share/ConfiguredNewTrackingSiPattern.py b/InnerDetector/InDetExample/InDetRecExample/share/ConfiguredNewTrackingSiPattern.py index 641770f10935c4e0bc847cabb9f8c12d617c6621..5f95152b346cf731f99c6b0d2800dbc2f9f724ee 100644 --- a/InnerDetector/InDetExample/InDetRecExample/share/ConfiguredNewTrackingSiPattern.py +++ b/InnerDetector/InDetExample/InDetRecExample/share/ConfiguredNewTrackingSiPattern.py @@ -92,11 +92,16 @@ class ConfiguredNewTrackingSiPattern: if NewTrackingCuts.mode() == "Offline" or InDetFlags.doHeavyIon() or NewTrackingCuts.mode() == "ForwardTracks": InDetSiSpacePointsSeedMaker.maxdImpactPPS = NewTrackingCuts.maxdImpactPPSSeeds() InDetSiSpacePointsSeedMaker.maxdImpactSSS = NewTrackingCuts.maxdImpactSSSSeeds() + if not InDetFlags.doHeavyIon(): InDetSiSpacePointsSeedMaker.maxSeedsForSpacePointStrips = NewTrackingCuts.MaxSeedsPerSP_Strips() InDetSiSpacePointsSeedMaker.maxSeedsForSpacePointPixels = NewTrackingCuts.MaxSeedsPerSP_Pixels() InDetSiSpacePointsSeedMaker.alwaysKeepConfirmedStripSeeds = NewTrackingCuts.KeepAllConfirmedStripSeeds() InDetSiSpacePointsSeedMaker.alwaysKeepConfirmedPixelSeeds = NewTrackingCuts.KeepAllConfirmedPixelSeeds() + InDetSiSpacePointsSeedMaker.mindRadius = 10. + # limit size of space-point vector, uses auto-grow mechanism + # to avoid exceeding bounds (should rarely happen) + InDetSiSpacePointsSeedMaker.maxSizeSP = 200 if NewTrackingCuts.mode() == "R3LargeD0": InDetSiSpacePointsSeedMaker.optimisePhiBinning = False diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiSpacePointsSeedMakerEventData.h b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiSpacePointsSeedMakerEventData.h index 9c089b2d4cc82723c116a49d139a45307e3c3e13..b036fdd90f65ab2f87c93d3173b4c8fc327050ef 100644 --- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiSpacePointsSeedMakerEventData.h +++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiSpacePointsSeedMakerEventData.h @@ -129,13 +129,13 @@ namespace InDet { /// The following are parameters characterising individual space points within a seed (relative to the central point) std::vector<float> Zo; ///< z0 estimate from 2 points - std::vector<float> Tz; ///< 1/sintheta estimate from 2 points + std::vector<float> Tz; ///< 1/tan(theta) == dz/dr estimate from 2 points std::vector<float> R; ///< inverse distance to the central space point std::vector<float> U; ///< transformed U coordinate (x/(x²+y²)) in frame around central SP std::vector<float> V; ///< transformed V coordinate (y/(x²+y²)) in frame around central SP std::vector<float> X; std::vector<float> Y; - std::vector<float> Er; + std::vector<float> Er; ///< error component on 1/tan(theta)==dz/dr from the position errors on the space-points //@} InDet::SiSpacePointsSeed seedOutput; @@ -189,6 +189,31 @@ namespace InDet { std::multimap<float,InDet::SiSpacePointsProSeedITK*> seeds_ITK; std::multimap<float,InDet::SiSpacePointsProSeedITK*>::iterator seed_ITK; + + /// allow to resize the space-point container on-the-fly in case + /// more space is needed. + /// This is a compromise to avoid a fixed array size while + /// still minimising the number of re-allocations + void resizeSPCont(size_t increment=50, ToolType type = ToolType::ATLxk){ + size_t currSize = SP.size(); + size_t newSize = currSize + increment; + if (type == ITK) { + SP_ITK.resize(newSize, nullptr); + X.resize(newSize, 0.); + Y.resize(newSize, 0.); + } else { + SP.resize(newSize, nullptr); + } + R.resize(newSize, 0.); + Tz.resize(newSize, 0.); + Er.resize(newSize, 0.); + U.resize(newSize, 0.); + V.resize(newSize, 0.); + if (type != Cosmic) { + Zo.resize(newSize, 0.); + } + } + /// Initialize data members based on ToolType enum. /// This method has to be called just after creation in SiSPSeededTrackFinder. void initialize(ToolType type, @@ -205,22 +230,7 @@ namespace InDet { } else if (type==ITK) { CmSp_ITK.reserve(500); } - - if (type==ITK) { - SP_ITK.resize(maxsizeSP, nullptr); - X.resize(maxsizeSP, 0.); - Y.resize(maxsizeSP, 0.); - } else { - SP.resize(maxsizeSP, nullptr); - } - R.resize(maxsizeSP, 0.); - Tz.resize(maxsizeSP, 0.); - Er.resize(maxsizeSP, 0.); - U.resize(maxsizeSP, 0.); - V.resize(maxsizeSP, 0.); - if (type!=Cosmic) { - Zo.resize(maxsizeSP, 0.); - } + resizeSPCont(maxsizeSP,type); seedPerSpCapacity = maxOneSize; if (type==ATLxk) { OneSeeds_Pro.resize(maxOneSize); diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h index 6cd3f61614d7bb33c72ee73bc7f7ce770f061149..b20a86b919b1d086ffac3e6b781bbf3e66f1779f 100644 --- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h +++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/SiSpacePointsSeedTool_xk/SiSpacePointsSeedMaker_ATLxk.h @@ -246,7 +246,7 @@ namespace InDet { float m_dzdrmax0{0.}; ///< implicitly store eta cut float m_ipt{0.}; ///< inverse of 90% of the ptmin cut float m_ipt2{0.}; ///< inverse square of 90% of the pt min cut - static constexpr float m_COF{134*.05*9}; ///< conversion factor. A very magic number indeed. + static constexpr float m_COF{134*.05*9}; ///< appears to be an approximated term related to multiple-scattering of particles traversing the ID during the seed formation /// @name Binning parameters ///@{ @@ -417,7 +417,7 @@ namespace InDet { std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endBottomCands, std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_topCands, std::array<std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endTopCands, - const int numberBottomCells, const int numberTopCells, int& nseed) const; + const int numberBottomCells, const int numberTopCells, int& nseed, const int zbin = -1) const; /// as above, but for the trigger void production3SpTrigger diff --git a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx index 580daefcd4231c3110f26866c1112b778a4a549d..9c5bbb9b71edb7559d742abeab5366d07499767e 100644 --- a/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx +++ b/InnerDetector/InDetRecTools/SiSpacePointsSeedTool_xk/src/SiSpacePointsSeedMaker_ATLxk.cxx @@ -1250,6 +1250,20 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::fillLists(EventData& data) const * For the second iteration, we reset it to zero and thus start in the pixels. **/ + const std::map<float, int> ztoBin{ + {-2500. ,0}, + {-1400. ,1}, + {-925. ,2}, + {-450. ,3}, + {-250 ,4}, + { 250 ,5}, + { 450 ,6}, + { 925 ,7}, + { 1400 ,8}, + { 2500 ,9}, + { 100000 ,10}, ///< if we encounter Si hits at z > +100m, we are probably not in ATLAS anymore... + }; + for (int radialBin=data.r_first; radialBin<m_nBinsR; ++radialBin) { /// skip empty radial bins @@ -1307,19 +1321,6 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::fillLists(EventData& data) const * a logN lookup speed **/ int zBin{0}; - const std::map<float, int> ztoBin{ - {-2500. ,0}, - {-1400. ,1}, - {-925. ,2}, - {-450. ,3}, - {-250 ,4}, - { 250 ,5}, - { 450 ,6}, - { 925 ,7}, - { 1400 ,8}, - { 2500 ,9}, - { 100000 ,10}, ///< if we encounter Si hits at z > +100m, we are probably not in ATLAS anymore... - }; auto bound = ztoBin.lower_bound(Z); /// some protection in case things go REALLY wrong if (bound == ztoBin.end()){ @@ -1605,7 +1606,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp(EventData& data) const } /// now run the seed search for the current phi-z bin. - if (!data.trigger) production3Sp (data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed); + if (!data.trigger) production3Sp (data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed,zBinIndex[z]); else production3SpTrigger(data, iter_bottomCands, iter_endBottomCands, iter_topCands, iter_endTopCands, numberBottomCells, numberTopCells, nseed); } @@ -1635,7 +1636,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endBottomCands, std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_topCands , std::array <std::vector<InDet::SiSpacePointForSeed*>::iterator, arraySizeNeighbourBins> & iter_endTopCands, - const int numberBottomCells, const int numberTopCells, int& nseed) const + const int numberBottomCells, const int numberTopCells, int& nseed, const int zbin) const { /** * This methid implements the seed search for a single phi-Z region of the detector. @@ -1647,14 +1648,39 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp std::vector<InDet::SiSpacePointForSeed*>::iterator iter_centralSP=iter_bottomCands[0]; std::vector<InDet::SiSpacePointForSeed*>::iterator iter_otherSP; ///< will be used for iterating over top/bottom SP - /// radial interval for the central SP. - /// For the PPP (PPS) pass, take Pixel layers 1,2,3 - float rmin = 40.; - float rmax = 140.; + /** + * Next, we work out where we are within the ATLAS geometry. + * This will help us identify which space-points we need to + * consider as potential central points of a seed. + **/ + + /// identify if we are looking at pixel or strip space points + bool isStrip = ((*iter_centralSP)->spacepoint->clusterList().second); + + /// bins 4,5,6 are the region in z = +/- 450 mm - "barrel like" in terms + /// of hit locations + bool isBarrelRegion = (zbin >=4 && zbin <= 6); + bool isTransitionRegion = (zbin == 3 || zbin == 7); // region in z = 450 - 925mm + float rmin = 40.; /// the central SP should not be in the IBL (nothing could go below) + float rmax = 140.; /// in the pixels, the highest-up SP can be fairly far out along the disk + + if (isBarrelRegion){ + rmax = 100; /// in the barrel pixels, we also remove the outermost layer from the central SP search + } /// for strip seed formation, allow most of the strip volume - if((*iter_centralSP)->spacepoint->clusterList().second) { - rmin = 280.; - rmax = 540.; + if(isStrip) { + /// default behaviour, applies in the forward region + rmin = 285.; /// start slightly above the lowest r occuring in the SCT for the central SP + rmax = 450.; /// for the central SP, do not go all the way to the upper edge of a disk. + if (isBarrelRegion){ + rmin = 335; /// in the barrel avoid the first strip layer for the central SP + rmax = 450.; /// skip last barrel layer as well - there must be a hit beyond + } + else if (isTransitionRegion){ + rmin = 335; /// in the transition also avoid the first strip layer for the central SP + rmax = 550; /// here, actually go higher than otherwise, to catch the ~full extent of the + /// first two disks. We manually exclude the flat barrel part below + } } /// find the first central SP candidate above the minimum radius. @@ -1679,6 +1705,10 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp const float& dzdrmin = data.dzdrmin; data.CmSp.clear(); + /// keep track of the SP storace capacity. + /// Extend it needed (should rarely be the case) + size_t SPcapacity = data.SP.size(); + /// Loop through all central space point candidates for (; iter_centralSP!=iter_endBottomCands[0]; ++iter_centralSP) { @@ -1690,16 +1720,25 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp const float& Y = (*iter_centralSP)->y(); const float& Z = (*iter_centralSP)->z(); + /// for the central SP, we veto locations on the last disk - + /// there would be no "outer" hits to complete a seed. + double absZ = std::abs(Z); + /// veto the last strip disk + if (isStrip && absZ > 2650. ) continue; + /// veto the last pixel disk + if (!isStrip && absZ > 600.) continue; + /// veto strip barrel layer 4 in the transition region + if (isStrip && isTransitionRegion && absZ < 750. && R > 450.) continue; + /// initialise a counter for found bottom links /// This also serves as an index in the data.SP vector - int Nb = 0; + size_t Nb = 0; /// Bottom links production /// Loop over all the cells where we expect to find such SP - bool abortBottomLoop=false; - for (int cell=0; !abortBottomLoop && cell<numberBottomCells; ++cell) { + for (int cell=0; cell<numberBottomCells; ++cell) { /// in each cell, loop over the space points - for (iter_otherSP=iter_bottomCands[cell]; !abortBottomLoop && iter_otherSP!=iter_endBottomCands[cell]; ++iter_otherSP) { + for (iter_otherSP=iter_bottomCands[cell]; iter_otherSP!=iter_endBottomCands[cell]; ++iter_otherSP) { /// evaluate the radial distance between the central and bottom SP const float& Rb =(*iter_otherSP)->radius(); @@ -1719,6 +1758,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp const float dZdR = (Z-(*iter_otherSP)->z())/dR; /// and abs value const float absdZdR = std::abs(dZdR); + /// this is effectively a segment-level eta cut - exclude too shallow seed segments if (absdZdR < dzdrmin or absdZdR > dzdrmax) continue; /// Comparison with vertices Z coordinates @@ -1727,26 +1767,30 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp if(z0 > zmax || z0 < zmin) continue; /// found a bottom SP candidate, write it into the data object data.SP[Nb] = (*iter_otherSP); - /// abort if we exceed the capacity for saving space points - if (++Nb==m_maxsizeSP) abortBottomLoop=true; + /// if we are exceeding the SP capacity of our data object, + /// make it resize its vectors. Will add 50 slots by default, + /// so rarely should happen more than once per event. + if (++Nb==SPcapacity){ + data.resizeSPCont(); + SPcapacity=data.SP.size(); + } } ///< end of loop over SP in bottom candidate cell } ///< end of loop over bottom candidate cells /// if we did not find ANY bottom SP, or if we exceed the storage capacity, we abort this seed candidate. - if (!Nb || Nb==m_maxsizeSP) continue; + if (!Nb) continue; /// now continue with the top SP search. /// Make the counter start at Nb, as this serves as a running /// index in the SP list for this seed. - int Nt = Nb; + size_t Nt = Nb; /// Top links production - bool abortTopLoop=false; /// again, loop over cells of interest, this time for the top SP candidate - for (int cell=0; !abortTopLoop && cell<numberTopCells; ++cell) { + for (int cell=0; cell<numberTopCells; ++cell) { /// loop over each SP in each cell - for (iter_otherSP=iter_topCands[cell]; !abortTopLoop && iter_otherSP!=iter_endTopCands[cell]; ++iter_otherSP) { + for (iter_otherSP=iter_topCands[cell];iter_otherSP!=iter_endTopCands[cell]; ++iter_otherSP) { /// evaluate the radial distance, float Rt =(*iter_otherSP)->radius(); @@ -1771,8 +1815,13 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp if(z0 > zmax || z0 < zmin) continue; /// add SP to the list data.SP[Nt] = (*iter_otherSP); - /// check capacity exceeding abort condition - if (++Nt==m_maxsizeSP) abortTopLoop=true; + /// if we are exceeding the SP capacity of our data object, + /// make it resize its vectors. Will add 50 slots by default, + /// so rarely should happen more than once per event. + if (++Nt==SPcapacity) { + data.resizeSPCont(); + SPcapacity=data.SP.size(); + } } ///< end of loop over SP within top candidate cell } ///< end of loop over top candidate cells @@ -1789,7 +1838,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp /// check all SP candidates we found during our loop and /// compute geometrical variables w.r.t the central point. - for (int i=0; i<Nt; ++i) { + for (size_t i=0; i<Nt; ++i) { InDet::SiSpacePointForSeed* sp = data.SP[i]; @@ -1806,7 +1855,7 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp /// inverse distance of the candidate space point to the central point float dr = sqrt(r2); /// estimate slope in z - distance traveled in transverse plane vs z direction. - /// rough estimate of 1/sin theta from 2 points + /// rough estimate of 1/tan theta from 2 points float tz = dz*dr; /// if we are looking at a bottom SP candidate, flip the sign to account for @@ -1814,49 +1863,57 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp if (i < Nb) tz = -tz; /// save this into our data object - data.Tz[i] = tz; ///< 1/ sin theta + data.Tz[i] = tz; ///< 1/ tan theta data.Zo[i] = Z-R*tz; ///< z0 estimate. data.R [i] = dr; ///< inverse distance to central SP data.U [i] = x*r2; ///< transformed U coordinate data.V [i] = y*r2; ///< transformed V coordinate - data.Er[i] = ((covz0+sp->covz())+(tz*tz)*(covr0+sp->covr()))*r2; ///< 1/r² (cov(z)) + 1/r²sin²theta cov(r) + data.Er[i] = ((covz0+sp->covz())+(tz*tz)*(covr0+sp->covr()))*r2; ///<squared Error on 1/tan theta coming from the space-point position errors } - /// tweak covariance matrix elements - covr0 *= .5; - covz0 *= 2.; - data.nOneSeeds = 0; data.mapOneSeeds_Pro.clear(); /// Three space points comparison /// first, loop over the bottom point candidates - for (int b=0; b<Nb; ++b) { + for (size_t b=0; b<Nb; ++b) { /// retrieve the geometrical paranmeters w.r.t the central SP for this candidate float Zob = data.Zo[b]; ///< z0 estimate from central+bottom SP - float Tzb = data.Tz[b]; ///< 1/sintheta estimate from central+bottom SP - float Rb2r = data.R [b]*covr0; ///< inverse distance times covariance on r coordinate - float Rb2z = data.R [b]*covz0; ///< inverse distance times covariance on z coordinate - float Erb = data.Er[b]; ///< 1/r² (cov(z)) + 1/r²sin²theta cov(r) + float Tzb = data.Tz[b]; ///< 1/tanTheta estimate from central+bottom SP + float Erb = data.Er[b]; ///< this is the uncertainty in 1/tanTheta on the bottom segment resulting from the position errors in the 2 SP float Vb = data.V [b]; ///< v-coordinate of bottom SP float Ub = data.U [b]; ///< u-coordinate of bottom SP - float Tzb2 = (1.+Tzb*Tzb); ///< 1+1/sin²theta - float sTzb2 = sqrt(Tzb2); ///< sqrt (1+1/sin²theta) - float CSA = Tzb2*COFK; ///< magic number x (1+1+sin²theta) - float ICSA = Tzb2*ipt2C; ///< magic number x inverse of 90% of the pt cut, squared x (1+1+sin²theta) + float Tzb2 = (1.+Tzb*Tzb); ///< 1+1/tan²theta - converts transverse to total squared pt + float sTzb2 = sqrt(Tzb2); ///< sqrt (1+1/tan²theta) - used to convert pt to |p| + float sigmaSquaredScatteringPtDependent = Tzb2*COFK; ///< this, when divided by the 2R², yields an approximated multiple scattering term assuming the measured pt. + float sigmaSquaredScatteringMinPt = Tzb2*ipt2C; ///< this is an approximate worst case multiple scattering term assuming the lowest + /// pt we allow and the estimated theta angle /// max IP float d0max = maxd0cut; /// for strips, apply the strip version of the IP cut if (data.SP[b]->spacepoint->clusterList().second) d0max = maxd0cutstrips; /// inner loop over the top point candidates - for (int t=Nb; t<Nt; ++t) { + for (size_t t=Nb; t<Nt; ++t) { - /// this appears to be an eta-compatibility cut between the two segments - float dT = ((Tzb-data.Tz[t])*(Tzb-data.Tz[t])-data.R[t]*Rb2z-(Erb+data.Er[t])) - -(data.R[t]*Rb2r)*((Tzb+data.Tz[t])*(Tzb+data.Tz[t])); - if (dT > ICSA) continue; + /// Apply a cut on the compatibility between the r-z slope of the two seed segments. + /// This is done by comparing the squared difference between slopes, and comparing + /// to the squared uncertainty in this difference - we keep a seed if the difference + /// is compatible within the assumed uncertainties. + + /// average value of 1/tan(theta), approximate the slope at the location of the central space point + float meanOneOverTanTheta = (Tzb+data.Tz[t])/2.; + /// squared error on the difference in tan(theta) due to space point position errors. + float sigmaSquaredSpacePointErrors = Erb+data.Er[t] /// pre-computed individual squared errors on 1/tan(theta) for the two segments + + 2. * covz0 * data.R[t]*data.R[b] /// mixed term with z-uncertainty on central SP + + 2. * covr0 * data.R[t]*data.R[b] * meanOneOverTanTheta * meanOneOverTanTheta; // mixed term with r-uncertainy on central SP + /// start out by subtracting from the squared difference in 1/tanTheta the space-point-related squared error + float remainingSquaredDelta = (Tzb-data.Tz[t])*(Tzb-data.Tz[t]) - sigmaSquaredSpacePointErrors; + + /// First, we test using a generous scattering term calculated assuming the minimum pt we expect + /// to reconstruct. + if (remainingSquaredDelta - sigmaSquaredScatteringMinPt > 0 ) continue; /** * The following exploits the transformation u:=x/(x²+y²); v:=y/(x²+y²); @@ -1885,12 +1942,20 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp float B = Vb-A*Ub; ///< B parameter, V axis intercept of the seed point distribution in the U,V plane float onePlusAsquare = 1.+A*A; float BSquare = B*B; + /** With this radius (and pT) estimate, we can apply our pt cut. * Reminder, ipt2K is 1 / (K x 0.9 x pt-cut)², where K translates pt into 2R. * So here we can apply the pt cut directly on the (2R)² estimate without - * the extra overhead of conversion / division - **/ - if (BSquare > ipt2K*onePlusAsquare || dT*onePlusAsquare > BSquare*CSA) continue; + * the extra overhead of conversion / division. + * The second check is a refinement of the above Tz compatibility cut, + * replacing the sigmaSquaredScatteringMinPt scattering contribution which assumes the lowest pt + * by one based on the actual estimated pt. + * + * The second term in this if-statement applies a second version of the + * 1/tan(theta) compatibility, this time using a scattering term scaled by the actual measured + * pt. This refines the cut applied above, following the same logic ("delta² - sigma² ?<=0") + **/ + if (BSquare > ipt2K*onePlusAsquare || remainingSquaredDelta*onePlusAsquare > BSquare*sigmaSquaredScatteringPtDependent) continue; /** This is an estimate of the transverse impact parameter. * The reasoning is that, in the x-y frame with the central SP as origin and @@ -1908,13 +1973,14 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::production3Sp * Note that below, the variable R is the radial coordinate fo the central SP, * corresponding to r_central in the notation above. **/ - float d0 = 0; - if(std::abs(B) < 1e-10) d0 = std::abs((A-B*R)*R); - else{ - float x0 = -A/(2.*B); - float rTrack = std::sqrt(onePlusAsquare/BSquare)*.5; - d0 = std::abs(-rTrack + std::sqrt(rTrack*rTrack +2*x0*R +R*R)); - } + float d0 = 0; + if(std::abs(B) < 1e-10) d0 = std::abs((A-B*R)*R); + /// apply the precise d0 calculation if we don't have to worry about floating point exceptions + else{ + float x0 = -A/(2.*B); + float rTrack = std::sqrt(onePlusAsquare/BSquare)*.5; + d0 = std::abs(-rTrack + std::sqrt(rTrack*rTrack +2*x0*R +R*R)); + } /// apply d0 cut to seed if (d0 <= d0max) { @@ -2277,11 +2343,12 @@ void InDet::SiSpacePointsSeedMaker_ATLxk::newOneSeedWithCurvaturesComparison /// if the other SP is too close to the current top one, skip float radiusOtherSP = (*it_otherSP).second->radius(); if (std::abs(radiusOtherSP-radiusTopSP) < m_drmin) continue; - /// if we have a confirmation seed, we improve the score of the seed. + // if we have a confirmation seed, we improve the score of the seed. seedQuality += m_seedScoreBonusConfirmationSeed; - /// only look for one confirmation seed! - break; + // apply confirmation bonus only once + break; } + /// kick this seed candidate if the score is too high (lower values = better) if (seedQuality > data.maxScore) continue; diff --git a/Tools/PROCTools/data/master_q221_AOD_digest.ref b/Tools/PROCTools/data/master_q221_AOD_digest.ref index 43704e767d56879397d9dace574ffb432e22c1b9..d31f7ad43ae12699105ebcb2f9c8d3caa017c337 100644 --- a/Tools/PROCTools/data/master_q221_AOD_digest.ref +++ b/Tools/PROCTools/data/master_q221_AOD_digest.ref @@ -4,23 +4,23 @@ 284500 87473022 38 29 4 0 4 1 3 3 2 1 284500 87473032 30 33 4 1 10 4 6 5 2 3 284500 87473037 62 39 7 0 12 2 10 6 4 2 - 284500 87473040 107 96 10 0 17 1 16 10 5 5 + 284500 87473040 107 97 10 0 17 1 16 10 5 5 284500 87473051 140 112 11 1 15 1 14 23 16 7 284500 87473063 62 76 5 2 7 1 6 6 4 2 - 284500 87473068 25 35 1 1 0 0 0 0 0 0 + 284500 87473068 25 34 1 1 0 0 0 0 0 0 284500 87473075 60 85 6 0 5 0 5 6 5 1 - 284500 87473084 78 86 7 2 14 1 13 10 3 7 + 284500 87473084 78 85 7 2 14 1 13 9 3 6 284500 87473091 41 49 3 0 4 2 2 4 2 2 - 284500 87473096 66 76 3 2 3 0 3 4 3 1 - 284500 87473104 64 64 6 0 5 2 3 5 4 1 - 284500 87473114 89 81 7 2 12 1 11 9 6 3 + 284500 87473096 66 75 3 2 3 0 3 4 3 1 + 284500 87473104 64 63 6 0 5 1 4 4 3 1 + 284500 87473114 89 80 7 2 12 1 11 9 6 3 284500 87473121 93 100 6 3 15 3 12 7 6 1 - 284500 87473132 84 58 9 1 12 0 12 3 3 0 - 284500 87473137 94 71 8 3 15 0 15 8 8 0 + 284500 87473132 84 57 9 1 12 0 12 3 3 0 + 284500 87473137 94 70 8 3 15 0 15 8 8 0 284500 87473144 78 67 7 1 8 2 6 8 6 2 284500 87473154 86 89 7 0 13 2 11 9 4 5 284500 87473162 53 52 4 0 7 0 7 3 2 1 284500 87473167 77 54 6 3 13 2 11 13 8 5 - 284500 87473171 77 70 8 4 4 2 2 5 4 1 + 284500 87473171 77 69 8 4 4 2 2 5 4 1 284500 87473184 75 86 5 2 8 1 7 5 3 2 284500 87473192 55 52 4 1 8 4 4 4 3 1 diff --git a/Tools/PROCTools/data/master_q431_AOD_digest.ref b/Tools/PROCTools/data/master_q431_AOD_digest.ref index 519f0aa6990e1daefa4bf13b64fd2dec378d4b73..80b9f27ae0359a7a4f8f2fa83d777ff257521285 100644 --- a/Tools/PROCTools/data/master_q431_AOD_digest.ref +++ b/Tools/PROCTools/data/master_q431_AOD_digest.ref @@ -1,26 +1,26 @@ run event nTopo nIdTracks nJets nMuons 330470 1183722158 1 0 0 0 - 330470 1183722342 394 411 20 0 - 330470 1183727953 532 572 11 4 - 330470 1183732647 467 451 13 1 + 330470 1183722342 394 406 20 0 + 330470 1183727953 532 566 11 4 + 330470 1183732647 467 449 13 1 330470 1183733040 381 284 6 1 - 330470 1183734651 361 360 14 3 - 330470 1183735332 406 372 9 1 - 330470 1183736475 741 651 15 3 + 330470 1183734651 361 357 14 3 + 330470 1183735332 406 371 9 1 + 330470 1183736475 741 647 15 3 330470 1183738728 1 0 0 0 - 330470 1183738949 368 424 9 1 - 330470 1183742489 152 124 2 1 - 330470 1183743040 285 306 5 0 - 330470 1183746343 492 465 14 0 + 330470 1183738949 368 421 9 1 + 330470 1183742489 152 123 2 1 + 330470 1183743040 285 305 5 0 + 330470 1183746343 492 459 14 0 330470 1183746710 6 0 0 0 - 330470 1183751782 239 234 4 0 - 330470 1183752624 347 343 8 3 - 330470 1183753006 357 377 11 3 - 330470 1183754806 470 405 15 0 + 330470 1183751782 239 231 5 0 + 330470 1183752624 347 338 8 3 + 330470 1183753006 357 375 11 3 + 330470 1183754806 470 404 15 0 330470 1183769295 342 317 8 2 - 330470 1183769939 348 342 11 3 + 330470 1183769939 348 341 11 3 330470 1183773832 307 199 7 0 330470 1183775209 57 0 0 0 - 330470 1183787124 431 360 11 2 - 330470 1183787946 321 311 5 1 - 330470 1183795329 458 332 18 0 + 330470 1183787124 431 359 11 2 + 330470 1183787946 321 310 5 1 + 330470 1183795329 458 331 18 0