diff --git a/CondFormats/SiPixelTransient/interface/SiPixelTemplate.h b/CondFormats/SiPixelTransient/interface/SiPixelTemplate.h index 2b9990fd83b5d..7408ec5c8698a 100644 --- a/CondFormats/SiPixelTransient/interface/SiPixelTemplate.h +++ b/CondFormats/SiPixelTransient/interface/SiPixelTemplate.h @@ -285,8 +285,9 @@ class SiPixelTemplate { // initialize the rest; static void postInit(std::vector& thePixelTemp_); + // Interpolate with y Gaussian Parameter interpolation to be used with goodEdge reconstruction algorithm // Interpolate input alpha and beta angles to produce a working template for each individual hit. - bool interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx); + bool interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx, bool goodEdgeAlgo = false); // Interpolate input alpha and beta angles to produce a working template for each individual hit. bool interpolate(int id, float cotalpha, float cotbeta, float locBz); diff --git a/CondFormats/SiPixelTransient/src/SiPixelTemplate.cc b/CondFormats/SiPixelTransient/src/SiPixelTemplate.cc index 0e3c83505634a..c91bfe4a0f25d 100644 --- a/CondFormats/SiPixelTransient/src/SiPixelTemplate.cc +++ b/CondFormats/SiPixelTransient/src/SiPixelTemplate.cc @@ -82,6 +82,7 @@ // V10.21 - Address runtime issues in pushfile() for gcc 7.X due to using tempfile as char string + misc. cleanup [Petar] // V10.22 - Move templateStore to the heap, fix variable name in pushfile() [Petar] // V10.24 - Add sideload() + associated gymnastics [Petar and Oz] +// V10.25 - Restore y-residual Gaussian parameters [Morris] // Created by Morris Swartz on 10/27/06. // @@ -1324,15 +1325,18 @@ void SiPixelTemplate::postInit(std::vector& thePixelTemp_) //! \param locBx - (input) the sign of this quantity is used to determine whether to flip cot(alpha/beta)<0 quantities from cot(alpha/beta)>0 (FPix only) //! for Phase 1 FPix IP-related tracks, locBx/locBz > 0 for cot(alpha) > 0 and locBx/locBz < 0 for cot(alpha) < 0 //! for Phase 1 FPix IP-related tracks, locBx > 0 for cot(beta) > 0 and locBx < 0 for cot(beta) < 0 +//! \param goodEdgeAlgo - (input) Flag to turn on the y Gaussian Parameter interpolation to be used with goodEdge reconstruction algorithm // ************************************************************************************************************ -bool SiPixelTemplate::interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx) { +bool SiPixelTemplate::interpolate(int id, float cotalpha, float cotbeta, float locBz, float locBx, bool goodEdgeAlgo) { // Interpolate for a new set of track angles +#ifndef SI_PIXEL_TEMPLATE_STANDALONE //check for nan's if (!edm::isFinite(cotalpha) || !edm::isFinite(cotbeta)) { success_ = false; return success_; } +#endif // Local variables int i, j; @@ -1553,16 +1557,19 @@ bool SiPixelTemplate::interpolate(int id, float cotalpha, float cotbeta, float l } for (i = 0; i < 4; ++i) { - yavg_[i] = (1.f - yratio_) * thePixelTemp_[index_id_].enty[ilow].yavg[i] + - yratio_ * thePixelTemp_[index_id_].enty[ihigh].yavg[i]; - if (flip_y_) { - yavg_[i] = -yavg_[i]; - } yavg_[i] = (1.f - yratio_) * enty0_->yavg[i] + yratio_ * enty1_->yavg[i]; if (flip_y_) { yavg_[i] = -yavg_[i]; } yrms_[i] = (1.f - yratio_) * enty0_->yrms[i] + yratio_ * enty1_->yrms[i]; + + if (goodEdgeAlgo) { // restore y Gaussian Parameter interpolation + ygx0_[i] = (1.f - yratio_) * enty0_->ygx0[i] + yratio_ * enty1_->ygx0[i]; + if (flip_y_) { + ygx0_[i] = -ygx0_[i]; + } + ygsig_[i] = (1.f - yratio_) * enty0_->ygsig[i] + yratio_ * enty1_->ygsig[i]; + } //if(goodEdgeAlgo) chi2yavg_[i] = (1.f - yratio_) * enty0_->chi2yavg[i] + yratio_ * enty1_->chi2yavg[i]; chi2ymin_[i] = (1.f - yratio_) * enty0_->chi2ymin[i] + yratio_ * enty1_->chi2ymin[i]; chi2xavg[i] = (1.f - yratio_) * enty0_->chi2xavg[i] + yratio_ * enty1_->chi2xavg[i]; diff --git a/Configuration/ProcessModifiers/python/siPixelGoodEdgeAlgo_cff.py b/Configuration/ProcessModifiers/python/siPixelGoodEdgeAlgo_cff.py new file mode 100644 index 0000000000000..c37354bbc59b7 --- /dev/null +++ b/Configuration/ProcessModifiers/python/siPixelGoodEdgeAlgo_cff.py @@ -0,0 +1,4 @@ +import FWCore.ParameterSet.Config as cms + +# This modifier enables the good edge algorithm in pixel hit reconstruction that handles broken/truncated pixel cluster caused by radiation damage +siPixelGoodEdgeAlgo = cms.Modifier() diff --git a/Configuration/PyReleaseValidation/README.md b/Configuration/PyReleaseValidation/README.md index 4d9518ab0f74b..a15ef64756397 100644 --- a/Configuration/PyReleaseValidation/README.md +++ b/Configuration/PyReleaseValidation/README.md @@ -119,3 +119,4 @@ The offsets currently in use are: * 0.113: Activate OuterTracker inefficiency (PS-p: bias rails inefficiency; PS-s and SS: 5% bad strips) * 0.114: Activate OuterTracker inefficiency (PS-p: bias rails inefficiency; PS-s and SS: 10% bad strips) * 0.141: Activate emulation of the signal shape of the InnerTracker FE chip (CROC) +* 0.186: Run-3 goodEdgeAlgo CPE \ No newline at end of file diff --git a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py index d207d4325f260..4d04cf285098e 100644 --- a/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py +++ b/Configuration/PyReleaseValidation/python/upgradeWorkflowComponents.py @@ -648,6 +648,34 @@ def condition(self, fragment, stepList, key, hasHarvest): offset = 0.18, ) +# pixel GoodEdgeAlgo CPE workflows +class UpgradeWorkflow_siPixelGoodEdgeAlgo(UpgradeWorkflow): + def setup_(self, step, stepName, stepDict, k, properties): + if 'Reco' in step: + stepDict[stepName][k] = merge([{'--procModifiers': 'siPixelGoodEdgeAlgo'}, stepDict[step][k]]) + def condition(self, fragment, stepList, key, hasHarvest): + result = (fragment=="QCD_Pt_1800_2400_14" or fragment=="TTbar_14TeV" ) and any(y in key for y in ['2025']) + return result +upgradeWFs['siPixelGoodEdgeAlgo'] = UpgradeWorkflow_siPixelGoodEdgeAlgo( + steps = [ + 'Reco', + 'RecoFakeHLT', + 'RecoGlobal', + 'RecoGlobalFakeHLT', + 'RecoNano', + 'RecoNanoFakeHLT', + ], + PU = [ + 'Reco', + 'RecoFakeHLT', + 'RecoGlobal', + 'RecoGlobalFakeHLT', + 'RecoNano', + 'RecoNanoFakeHLT', + ], + suffix = '_siPixelGoodEdgeAlgo', + offset = 0.186, +) #Workflow to enable displacedRegionalStep tracking iteration class UpgradeWorkflow_displacedRegional(UpgradeWorkflowTracking): diff --git a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEClusterRepair.h b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEClusterRepair.h index 0e44e3907b9dd..5843e75cfc78d 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEClusterRepair.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPEClusterRepair.h @@ -102,6 +102,7 @@ class PixelCPEClusterRepair : public PixelCPEBase { std::vector thePixelTemp2D_; int speed_; + bool goodEdgeAlgo_; bool UseClusterSplitter_; diff --git a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h index dc92fae67d4c6..b4f034f9925a2 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h @@ -79,6 +79,7 @@ class PixelCPETemplateReco : public PixelCPEBase { const std::vector *thePixelTemp_; int speed_; + bool goodEdgeAlgo_; bool UseClusterSplitter_; diff --git a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateReco.h b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateReco.h index 51e434e812a60..0cd9e6bbb6906 100644 --- a/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateReco.h +++ b/RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateReco.h @@ -99,7 +99,26 @@ namespace SiPixelTemplateReco { std::vector >& zeropix, float& probQ, int& nypix, - int& nxpix); + int& nxpix, + bool goodEdgeAlgo); + + int PixelTempReco1D(int id, + float cotalpha, + float cotbeta, + float locBz, + float locBx, + ClusMatrix& cluster, + SiPixelTemplate& templ, + float& yrec, + float& sigmay, + float& proby, + float& xrec, + float& sigmax, + float& probx, + int& qbin, + int speed, + float& probQ, + bool goodEdgeAlgo); int PixelTempReco1D(int id, float cotalpha, diff --git a/RecoLocalTracker/SiPixelRecHits/python/PixelCPEClusterRepair_cfi.py b/RecoLocalTracker/SiPixelRecHits/python/PixelCPEClusterRepair_cfi.py index 7823d45144ae2..0eb7dbbb0d371 100644 --- a/RecoLocalTracker/SiPixelRecHits/python/PixelCPEClusterRepair_cfi.py +++ b/RecoLocalTracker/SiPixelRecHits/python/PixelCPEClusterRepair_cfi.py @@ -6,3 +6,8 @@ ComponentName = "PixelCPEClusterRepairWithoutProbQ", speed = 0 ) + +# Enable the good edge algorithm in pixel hit reconstruction that handles broken/truncated pixel cluster caused by radiation damage +from Configuration.ProcessModifiers.siPixelGoodEdgeAlgo_cff import siPixelGoodEdgeAlgo +siPixelGoodEdgeAlgo.toModify(templates2, GoodEdgeAlgo = True) +siPixelGoodEdgeAlgo.toModify(templates2_speed0, GoodEdgeAlgo = True) diff --git a/RecoLocalTracker/SiPixelRecHits/python/PixelCPETemplateReco_cfi.py b/RecoLocalTracker/SiPixelRecHits/python/PixelCPETemplateReco_cfi.py index 3c74bbe3c75ff..b2287a01d3875 100644 --- a/RecoLocalTracker/SiPixelRecHits/python/PixelCPETemplateReco_cfi.py +++ b/RecoLocalTracker/SiPixelRecHits/python/PixelCPETemplateReco_cfi.py @@ -3,3 +3,6 @@ from RecoLocalTracker.SiPixelRecHits._templates_default_cfi import _templates_default templates = _templates_default.clone() +# Enable the good edge algorithm in pixel hit reconstruction that handles broken/truncated pixel cluster caused by radiation damage +from Configuration.ProcessModifiers.siPixelGoodEdgeAlgo_cff import siPixelGoodEdgeAlgo +siPixelGoodEdgeAlgo.toModify(templates, GoodEdgeAlgo = True) diff --git a/RecoLocalTracker/SiPixelRecHits/src/PixelCPEClusterRepair.cc b/RecoLocalTracker/SiPixelRecHits/src/PixelCPEClusterRepair.cc index d2d8502daeea4..24fdb00d9edb3 100644 --- a/RecoLocalTracker/SiPixelRecHits/src/PixelCPEClusterRepair.cc +++ b/RecoLocalTracker/SiPixelRecHits/src/PixelCPEClusterRepair.cc @@ -75,7 +75,9 @@ PixelCPEClusterRepair::PixelCPEClusterRepair(edm::ParameterSet const& conf, } speed_ = conf.getParameter("speed"); + goodEdgeAlgo_ = conf.getParameter("GoodEdgeAlgo"); LogDebug("PixelCPEClusterRepair::PixelCPEClusterRepair:") << "Template speed = " << speed_ << "\n"; + LogDebug("PixelCPEClusterRepair::PixelCPEClusterRepair:") << "GoodEdgeAlgo = " << goodEdgeAlgo_ << "\n"; // this returns the magnetic field value in kgauss (1T = 10 kgauss) int theMagField = mag->nominalValue(); @@ -355,7 +357,8 @@ void PixelCPEClusterRepair::callTempReco1D(DetParam const& theDetParam, zeropix, theClusterParam.probabilityQ_, nypix, - nxpix); + nxpix, + goodEdgeAlgo_); // ****************************************************************** //--- Check exit status @@ -549,7 +552,8 @@ void PixelCPEClusterRepair::checkRecommend2D(DetParam const& theDetParam, } // The 1d pixel template SiPixelTemplate templ(*thePixelTemp_); - if (!templ.interpolate(ID, theClusterParam.cotalpha, theClusterParam.cotbeta, theDetParam.bz, theDetParam.bx)) { + if (!templ.interpolate( + ID, theClusterParam.cotalpha, theClusterParam.cotbeta, theDetParam.bz, theDetParam.bx, goodEdgeAlgo_)) { //error setting up template, return false theClusterParam.recommended2D_ = false; return; @@ -718,6 +722,7 @@ void PixelCPEClusterRepair::fillPSetDescription(edm::ParameterSetDescription& de desc.add("forwardTemplateID", 0); desc.add("directoryWithTemplates", 0); desc.add("speed", -2); + desc.add("GoodEdgeAlgo", false); desc.add("UseClusterSplitter", false); desc.add("MaxSizeMismatchInY", 0.3); desc.add("MinChargeRatio", 0.8); diff --git a/RecoLocalTracker/SiPixelRecHits/src/PixelCPETemplateReco.cc b/RecoLocalTracker/SiPixelRecHits/src/PixelCPETemplateReco.cc index beb2884ecd288..de04276201101 100644 --- a/RecoLocalTracker/SiPixelRecHits/src/PixelCPETemplateReco.cc +++ b/RecoLocalTracker/SiPixelRecHits/src/PixelCPETemplateReco.cc @@ -81,6 +81,7 @@ PixelCPETemplateReco::PixelCPETemplateReco(edm::ParameterSet const& conf, << " not loaded correctly from text file. Reconstruction will fail.\n\n"; } + goodEdgeAlgo_ = conf.getParameter("GoodEdgeAlgo"); speed_ = conf.getParameter("speed"); LogDebug("PixelCPETemplateReco::PixelCPETemplateReco:") << "Template speed = " << speed_ << "\n"; @@ -249,7 +250,8 @@ LocalPoint PixelCPETemplateReco::localPosition(DetParam const& theDetParam, Clus theClusterParam.templProbX_, theClusterParam.templQbin_, speed_, - theClusterParam.templProbQ_); + theClusterParam.templProbQ_, + goodEdgeAlgo_); // ****************************************************************** @@ -529,4 +531,5 @@ void PixelCPETemplateReco::fillPSetDescription(edm::ParameterSetDescription& des desc.add("directoryWithTemplates", 0); desc.add("speed", -2); desc.add("UseClusterSplitter", false); + desc.add("GoodEdgeAlgo", false); } diff --git a/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplateReco.cc b/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplateReco.cc index 78d0a97ee20de..4eeeff19f91b6 100644 --- a/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplateReco.cc +++ b/RecoLocalTracker/SiPixelRecHits/src/SiPixelTemplateReco.cc @@ -45,6 +45,8 @@ // V10.00 - Use new template object to reco Phase 1 FPix hits // V10.01 - Fix memory overwriting bug // V10.10 - Change VVIObjF so it only reads kappa +// V10.30 - Use "good" end to center the y-projections [for high eta radiation damage], +// - use Gaussian fit paramters for y-bias and y-errors, remove chi2min_y warning // // // Created by Morris Swartz on 10/27/06. @@ -131,6 +133,7 @@ using namespace SiPixelTemplateReco; //! \param probQ - (output) the Vavilov-distribution-based cluster charge probability //! \param nypix - (output) the projected y-size of the cluster //! \param nxpix - (output) the projected x-size of the cluster +//! \param goodEdgeAlgo - (input) bool to indicate whether to use centering based on the good end of the cluster (compatible only with templates derived using the same) // ************************************************************************************************************************************* int SiPixelTemplateReco::PixelTempReco1D(int id, float cotalpha, @@ -151,7 +154,8 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, std::vector >& zeropix, float& probQ, int& nypix, - int& nxpix) + int& nxpix, + bool goodEdgeAlgo) { // Local variables @@ -186,7 +190,7 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, // check to see of the track direction is in the physical range of the loaded template if (id >= 0) { //if id < 0 bypass interpolation (used in calibration) - if (!templ.interpolate(id, cotalpha, cotbeta, locBz, locBx)) { + if (!templ.interpolate(id, cotalpha, cotbeta, locBz, locBx, goodEdgeAlgo)) { if (theVerboseLevel > 2) { LOGDEBUG("SiPixelTemplateReco") << "input cluster direction cot(alpha) = " << cotalpha << ", cot(beta) = " << cotbeta << ", local B_z = " << locBz @@ -463,8 +467,18 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, // next, center the cluster on template center if necessary - midpix = (fypix + lypix) / 2; - shifty = templ.cytemp() - midpix; + if (goodEdgeAlgo) { + if (cotbeta >= 0) { + midpix = (int)(fypix + 0.5 * cotbeta * templ.zsize() / ysize); + } else { + midpix = (int)(lypix + 0.5 * cotbeta * templ.zsize() / ysize); + } + shifty = BHY - midpix; + } //if(goodEdgeAlgo) + else { + midpix = (fypix + lypix) / 2; + shifty = templ.cytemp() - midpix; + } //else // calculate new cluster boundaries @@ -913,12 +927,19 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, // Now calculate the mean bias correction and uncertainties float qyfrac = (qfy - qly) / (qfy + qly); - bias = templ.yflcorr(binq, qyfrac) + templ.yavg(binq); + if (goodEdgeAlgo) { + bias = templ.yflcorr(binq, qyfrac) + templ.ygx0(binq); + } else { + bias = templ.yflcorr(binq, qyfrac) + templ.yavg(binq); + } // uncertainty and final correction depend upon charge bin - yrec = (0.125f * binl + BHY - 2.5f + rat * (binh - binl) * 0.125f - (float)shifty + originy) * ysize - bias; - sigmay = templ.yrms(binq); + if (goodEdgeAlgo) { + sigmay = templ.ygsig(binq); + } else { + sigmay = templ.yrms(binq); + } // Do goodness of fit test in y @@ -1202,6 +1223,89 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, return 0; } // PixelTempReco1D +// ************************************************************************************************************************************* +// Overload parameter list for compatibility with older versions +//! Reconstruct the best estimate of the hit position for pixel clusters. +//! \param id - (input) identifier of the template to use +//! \param cotalpha - (input) the cotangent of the alpha track angle (see CMS IN 2004/014) +//! \param cotbeta - (input) the cotangent of the beta track angle (see CMS IN 2004/014) +//! \param locBz - (input) the sign of this quantity is used to determine whether to flip cot(beta)<0 quantities from cot(beta)>0 (FPix only) +//! for Phase 0 FPix IP-related tracks, locBz < 0 for cot(beta) > 0 and locBz > 0 for cot(beta) < 0 +//! for Phase 1 FPix IP-related tracks, see next comment +//! \param locBx - (input) the sign of this quantity is used to determine whether to flip cot(alpha/beta)<0 quantities from cot(alpha/beta)>0 (FPix only) +//! for Phase 1 FPix IP-related tracks, locBx/locBz > 0 for cot(alpha) > 0 and locBx/locBz < 0 for cot(alpha) < 0 +//! for Phase 1 FPix IP-related tracks, locBx > 0 for cot(beta) > 0 and locBx < 0 for cot(beta) < 0//! \param cotbeta - (input) the cotangent of the beta track angle (see CMS IN 2004/014) +//! \param cluster - (input) boost multi_array container of 7x21 array of pixel signals, +//! origin of local coords (0,0) at center of pixel cluster[0][0]. +//! \param ydouble - (input) STL vector of 21 element array to flag a double-pixel +//! \param xdouble - (input) STL vector of 7 element array to flag a double-pixel +//! \param templ - (input) the template used in the reconstruction +//! \param yrec - (output) best estimate of y-coordinate of hit in microns +//! \param sigmay - (output) best estimate of uncertainty on yrec in microns +//! \param proby - (output) probability describing goodness-of-fit for y-reco +//! \param xrec - (output) best estimate of x-coordinate of hit in microns +//! \param sigmax - (output) best estimate of uncertainty on xrec in microns +//! \param probx - (output) probability describing goodness-of-fit for x-reco +//! \param qbin - (output) index (0-4) describing the charge of the cluster +//! [0: 1.5 > zeropix; + int nypix, nxpix; + + return SiPixelTemplateReco::PixelTempReco1D(id, + cotalpha, + cotbeta, + locBz, + locBx, + cluster, + templ, + yrec, + sigmay, + proby, + xrec, + sigmax, + probx, + qbin, + speed, + deadpix, + zeropix, + probQ, + nypix, + nxpix, + goodEdgeAlgo); + +} // PixelTempReco1D + // ************************************************************************************************************************************* // Overload parameter list for compatibility with older versions //! Reconstruct the best estimate of the hit position for pixel clusters. @@ -1258,6 +1362,7 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, const bool deadpix = false; std::vector > zeropix; int nypix, nxpix; + const bool goodEdgeAlgo = false; return SiPixelTemplateReco::PixelTempReco1D(id, cotalpha, @@ -1278,7 +1383,8 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, zeropix, probQ, nypix, - nxpix); + nxpix, + goodEdgeAlgo); } // PixelTempReco1D @@ -1328,6 +1434,7 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, { // Local variables const bool deadpix = false; + const bool goodEdgeAlgo = false; std::vector > zeropix; int nypix, nxpix; float locBx, locBz; @@ -1359,7 +1466,8 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, zeropix, probQ, nypix, - nxpix); + nxpix, + goodEdgeAlgo); } // PixelTempReco1D @@ -1405,6 +1513,7 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, { // Local variables const bool deadpix = false; + const bool goodEdgeAlgo = false; std::vector > zeropix; int nypix, nxpix; float locBx, locBz; @@ -1441,6 +1550,7 @@ int SiPixelTemplateReco::PixelTempReco1D(int id, zeropix, probQ, nypix, - nxpix); + nxpix, + goodEdgeAlgo); } // PixelTempReco1D