File indexing completed on 2025-06-25 05:16:13
0001
0002 #include "RecoLocalTracker/SiPixelRecHits/interface/PixelCPETemplateReco.h"
0003
0004
0005 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0006
0007
0008
0009
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011
0012
0013 #include "MagneticField/Engine/interface/MagneticField.h"
0014
0015
0016 #include "RecoLocalTracker/SiPixelRecHits/interface/SiPixelTemplateReco.h"
0017
0018
0019
0020
0021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0022
0023 #include <vector>
0024 #include "boost/multi_array.hpp"
0025
0026 #include <iostream>
0027
0028 using namespace SiPixelTemplateReco;
0029
0030 using namespace std;
0031
0032 namespace {
0033 constexpr float micronsToCm = 1.0e-4;
0034 constexpr int cluster_matrix_size_x = 13;
0035 constexpr int cluster_matrix_size_y = 21;
0036 }
0037
0038
0039
0040
0041
0042 PixelCPETemplateReco::PixelCPETemplateReco(edm::ParameterSet const& conf,
0043 const MagneticField* mag,
0044 const TrackerGeometry& geom,
0045 const TrackerTopology& ttopo,
0046 const SiPixelLorentzAngle* lorentzAngle,
0047 const std::vector<SiPixelTemplateStore>* templateStore,
0048 const SiPixelTemplateDBObject* templateDBobject)
0049 : PixelCPEBase(conf, mag, geom, ttopo, lorentzAngle, nullptr, templateDBobject, nullptr, 1) {
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 if (LoadTemplatesFromDB_) {
0064
0065 thePixelTemp_ = templateStore;
0066 } else {
0067
0068 barrelTemplateID_ = conf.getParameter<int>("barrelTemplateID");
0069 forwardTemplateID_ = conf.getParameter<int>("forwardTemplateID");
0070 templateDir_ = conf.getParameter<int>("directoryWithTemplates");
0071
0072 thePixelTemp_ = &thePixelTempCache_;
0073 if (!SiPixelTemplate::pushfile(barrelTemplateID_, thePixelTempCache_, templateDir_))
0074 throw cms::Exception("PixelCPETemplateReco")
0075 << "\nERROR: Template ID " << barrelTemplateID_
0076 << " not loaded correctly from text file. Reconstruction will fail.\n\n";
0077
0078 if (!SiPixelTemplate::pushfile(forwardTemplateID_, thePixelTempCache_, templateDir_))
0079 throw cms::Exception("PixelCPETemplateReco")
0080 << "\nERROR: Template ID " << forwardTemplateID_
0081 << " not loaded correctly from text file. Reconstruction will fail.\n\n";
0082 }
0083
0084 goodEdgeAlgo_ = conf.getParameter<bool>("GoodEdgeAlgo");
0085 speed_ = conf.getParameter<int>("speed");
0086 LogDebug("PixelCPETemplateReco::PixelCPETemplateReco:") << "Template speed = " << speed_ << "\n";
0087
0088 UseClusterSplitter_ = conf.getParameter<bool>("UseClusterSplitter");
0089 }
0090
0091
0092
0093
0094 PixelCPETemplateReco::~PixelCPETemplateReco() {}
0095
0096 std::unique_ptr<PixelCPEBase::ClusterParam> PixelCPETemplateReco::createClusterParam(const SiPixelCluster& cl) const {
0097 return std::make_unique<ClusterParamTemplate>(cl);
0098 }
0099
0100
0101
0102
0103
0104
0105
0106
0107 LocalPoint PixelCPETemplateReco::localPosition(DetParam const& theDetParam, ClusterParam& theClusterParamBase) const {
0108 ClusterParamTemplate& theClusterParam = static_cast<ClusterParamTemplate&>(theClusterParamBase);
0109
0110 if (!GeomDetEnumerators::isTrackerPixel(theDetParam.thePart))
0111 throw cms::Exception("PixelCPETemplateReco::localPosition :") << "A non-pixel detector type in here?";
0112
0113 const bool fpix = GeomDetEnumerators::isEndcap(theDetParam.thePart);
0114
0115 int ID = -9999;
0116 if (LoadTemplatesFromDB_) {
0117 int ID0 = templateDBobject_->getTemplateID(theDetParam.theDet->geographicalId());
0118 ID = theDetParam.detTemplateId;
0119 if (ID0 != ID)
0120 edm::LogError("PixelCPETemplateReco") << " different id" << ID << " " << ID0 << endl;
0121 } else {
0122 if (!fpix)
0123 ID = barrelTemplateID_;
0124 else
0125 ID = forwardTemplateID_;
0126 }
0127
0128
0129 SiPixelTemplate templ(*thePixelTemp_);
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140 int row_offset = theClusterParam.theCluster->minPixelRow();
0141 int col_offset = theClusterParam.theCluster->minPixelCol();
0142
0143
0144
0145
0146 float tmp_x = float(row_offset) + 0.5f;
0147 float tmp_y = float(col_offset) + 0.5f;
0148
0149
0150
0151
0152
0153
0154
0155
0156 float lorentzshiftX = 0.5f * theDetParam.lorentzShiftInCmX;
0157 float lorentzshiftY = 0.5f * theDetParam.lorentzShiftInCmY;
0158
0159
0160 LocalPoint lp;
0161
0162 if (theClusterParam.with_track_angle)
0163 lp = theDetParam.theTopol->localPosition(MeasurementPoint(tmp_x, tmp_y), theClusterParam.loc_trk_pred);
0164 else {
0165 edm::LogError("PixelCPETemplateReco") << "@SUB = PixelCPETemplateReco::localPosition"
0166 << "Should never be here. PixelCPETemplateReco should always be called with "
0167 "track angles. This is a bad error !!! ";
0168
0169 lp = theDetParam.theTopol->localPosition(MeasurementPoint(tmp_x, tmp_y));
0170 }
0171
0172
0173 int mrow = 0, mcol = 0;
0174 for (int i = 0; i != theClusterParam.theCluster->size(); ++i) {
0175 auto pix = theClusterParam.theCluster->pixel(i);
0176 int irow = int(pix.x);
0177 int icol = int(pix.y);
0178 mrow = std::max(mrow, irow);
0179 mcol = std::max(mcol, icol);
0180 }
0181 mrow -= row_offset;
0182 mrow += 1;
0183 mrow = std::min(mrow, cluster_matrix_size_x);
0184 mcol -= col_offset;
0185 mcol += 1;
0186 mcol = std::min(mcol, cluster_matrix_size_y);
0187 assert(mrow > 0);
0188 assert(mcol > 0);
0189
0190 float clustMatrix[mrow][mcol];
0191 memset(clustMatrix, 0, sizeof(float) * mrow * mcol);
0192
0193
0194 for (int i = 0; i != theClusterParam.theCluster->size(); ++i) {
0195 auto pix = theClusterParam.theCluster->pixel(i);
0196 int irow = int(pix.x) - row_offset;
0197 int icol = int(pix.y) - col_offset;
0198
0199
0200
0201 if ((irow < mrow) & (icol < mcol))
0202 clustMatrix[irow][icol] = float(pix.adc);
0203 }
0204
0205
0206 bool xdouble[mrow], ydouble[mcol];
0207
0208 for (int irow = 0; irow < mrow; ++irow)
0209 xdouble[irow] = theDetParam.theTopol->isItBigPixelInX(irow + row_offset);
0210
0211
0212 for (int icol = 0; icol < mcol; ++icol)
0213 ydouble[icol] = theDetParam.theTopol->isItBigPixelInY(icol + col_offset);
0214
0215 SiPixelTemplateReco::ClusMatrix clusterPayload{&clustMatrix[0][0], xdouble, ydouble, mrow, mcol};
0216
0217
0218 float nonsense = -99999.9f;
0219 theClusterParam.templXrec_ = theClusterParam.templYrec_ = theClusterParam.templSigmaX_ =
0220 theClusterParam.templSigmaY_ = nonsense;
0221
0222 theClusterParam.templProbY_ = theClusterParam.templProbX_ = theClusterParam.templProbQ_ = 1.0f;
0223 theClusterParam.templQbin_ = 0;
0224
0225 theClusterParam.hasFilledProb_ = false;
0226
0227 float templYrec1_ = nonsense;
0228 float templXrec1_ = nonsense;
0229 float templYrec2_ = nonsense;
0230 float templXrec2_ = nonsense;
0231
0232
0233
0234
0235 float locBz = theDetParam.bz;
0236 float locBx = theDetParam.bx;
0237
0238 theClusterParam.ierr = PixelTempReco1D(ID,
0239 theClusterParam.cotalpha,
0240 theClusterParam.cotbeta,
0241 locBz,
0242 locBx,
0243 clusterPayload,
0244 templ,
0245 theClusterParam.templYrec_,
0246 theClusterParam.templSigmaY_,
0247 theClusterParam.templProbY_,
0248 theClusterParam.templXrec_,
0249 theClusterParam.templSigmaX_,
0250 theClusterParam.templProbX_,
0251 theClusterParam.templQbin_,
0252 speed_,
0253 theClusterParam.templProbQ_,
0254 goodEdgeAlgo_);
0255
0256
0257
0258
0259 if UNLIKELY (theClusterParam.ierr != 0) {
0260 LogDebug("PixelCPETemplateReco::localPosition")
0261 << "reconstruction failed with error " << theClusterParam.ierr << "\n";
0262
0263
0264
0265
0266
0267 if (theClusterParam.with_track_angle) {
0268 theClusterParam.templXrec_ =
0269 theDetParam.theTopol->localX(theClusterParam.theCluster->x(), theClusterParam.loc_trk_pred) + lorentzshiftX;
0270 theClusterParam.templYrec_ =
0271 theDetParam.theTopol->localY(theClusterParam.theCluster->y(), theClusterParam.loc_trk_pred) + lorentzshiftY;
0272 } else {
0273 edm::LogError("PixelCPETemplateReco") << "@SUB = PixelCPETemplateReco::localPosition"
0274 << "Should never be here. PixelCPETemplateReco should always be called "
0275 "with track angles. This is a bad error !!! ";
0276
0277 theClusterParam.templXrec_ = theDetParam.theTopol->localX(theClusterParam.theCluster->x()) + lorentzshiftX;
0278 theClusterParam.templYrec_ = theDetParam.theTopol->localY(theClusterParam.theCluster->y()) + lorentzshiftY;
0279 }
0280 } else if UNLIKELY (UseClusterSplitter_ && theClusterParam.templQbin_ == 0) {
0281 edm::LogError("PixelCPETemplateReco") << " PixelCPETemplateReco: Qbin = 0 but using cluster splitter, we should "
0282 "never be here !!!!!!!!!!!!!!!!!!!!!! \n"
0283 << "(int)UseClusterSplitter_ = " << (int)UseClusterSplitter_ << endl;
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298 theClusterParam.ierr = -123;
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 if (theClusterParam.ierr != 0) {
0316
0317
0318
0319
0320 if (theClusterParam.with_track_angle) {
0321 theClusterParam.templXrec_ =
0322 theDetParam.theTopol->localX(theClusterParam.theCluster->x(), theClusterParam.loc_trk_pred) + lorentzshiftX;
0323 theClusterParam.templYrec_ =
0324 theDetParam.theTopol->localY(theClusterParam.theCluster->y(), theClusterParam.loc_trk_pred) + lorentzshiftY;
0325 } else {
0326 edm::LogError("PixelCPETemplateReco") << "@SUB = PixelCPETemplateReco::localPosition"
0327 << "Should never be here. PixelCPETemplateReco should always be called "
0328 "with track angles. This is a bad error !!! ";
0329 theClusterParam.templXrec_ = theDetParam.theTopol->localX(theClusterParam.theCluster->x()) + lorentzshiftX;
0330 theClusterParam.templYrec_ = theDetParam.theTopol->localY(theClusterParam.theCluster->y()) + lorentzshiftY;
0331 }
0332 } else {
0333
0334 templXrec1_ *= micronsToCm;
0335 templYrec1_ *= micronsToCm;
0336 templXrec2_ *= micronsToCm;
0337 templYrec2_ *= micronsToCm;
0338
0339
0340 templXrec1_ += lp.x();
0341 templYrec1_ += lp.y();
0342 templXrec2_ += lp.x();
0343 templYrec2_ += lp.y();
0344
0345
0346 float distX1 = std::abs(templXrec1_ - theClusterParam.trk_lp_x);
0347 float distX2 = std::abs(templXrec2_ - theClusterParam.trk_lp_x);
0348 float distY1 = std::abs(templYrec1_ - theClusterParam.trk_lp_y);
0349 float distY2 = std::abs(templYrec2_ - theClusterParam.trk_lp_y);
0350 theClusterParam.templXrec_ = (distX1 < distX2 ? templXrec1_ : templXrec2_);
0351 theClusterParam.templYrec_ = (distY1 < distY2 ? templYrec1_ : templYrec2_);
0352 }
0353 }
0354
0355 else
0356 {
0357
0358 theClusterParam.templXrec_ *= micronsToCm;
0359 theClusterParam.templYrec_ *= micronsToCm;
0360
0361
0362 theClusterParam.templXrec_ += lp.x();
0363 theClusterParam.templYrec_ += lp.y();
0364
0365
0366 if (doLorentzFromAlignment_) {
0367
0368 if (theDetParam.lorentzShiftInCmX != 0.0 || theDetParam.lorentzShiftInCmY != 0.0) {
0369
0370
0371
0372
0373
0374 float templateLorbiasCmX = -micronsToCm * templ.lorxbias();
0375 float templateLorbiasCmY = -micronsToCm * templ.lorybias();
0376
0377
0378
0379 theClusterParam.templXrec_ += (0.5 * (theDetParam.lorentzShiftInCmX) - templateLorbiasCmX);
0380 theClusterParam.templYrec_ += (0.5 * (theDetParam.lorentzShiftInCmY) - templateLorbiasCmY);
0381
0382
0383
0384
0385
0386
0387
0388 }
0389 }
0390 }
0391
0392
0393
0394 theClusterParam.probabilityX_ = theClusterParam.templProbX_;
0395 theClusterParam.probabilityY_ = theClusterParam.templProbY_;
0396 theClusterParam.probabilityQ_ = theClusterParam.templProbQ_;
0397 theClusterParam.qBin_ = theClusterParam.templQbin_;
0398
0399 if (theClusterParam.ierr == 0)
0400 theClusterParam.hasFilledProb_ = true;
0401
0402 return LocalPoint(theClusterParam.templXrec_, theClusterParam.templYrec_);
0403 }
0404
0405
0406
0407
0408 LocalError PixelCPETemplateReco::localError(DetParam const& theDetParam, ClusterParam& theClusterParamBase) const {
0409 ClusterParamTemplate& theClusterParam = static_cast<ClusterParamTemplate&>(theClusterParamBase);
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 float xerr, yerr;
0422
0423
0424 if (theClusterParam.theCluster->getSplitClusterErrorX() > 0.0f &&
0425 theClusterParam.theCluster->getSplitClusterErrorX() < clusterSplitMaxError_ &&
0426 theClusterParam.theCluster->getSplitClusterErrorY() > 0.0f &&
0427 theClusterParam.theCluster->getSplitClusterErrorY() < clusterSplitMaxError_) {
0428 xerr = theClusterParam.theCluster->getSplitClusterErrorX() * micronsToCm;
0429 yerr = theClusterParam.theCluster->getSplitClusterErrorY() * micronsToCm;
0430
0431
0432
0433
0434 } else {
0435
0436
0437
0438
0439 int maxPixelCol = theClusterParam.theCluster->maxPixelCol();
0440 int maxPixelRow = theClusterParam.theCluster->maxPixelRow();
0441 int minPixelCol = theClusterParam.theCluster->minPixelCol();
0442 int minPixelRow = theClusterParam.theCluster->minPixelRow();
0443
0444
0445 bool edgex =
0446 (theDetParam.theTopol->isItEdgePixelInX(minPixelRow) || theDetParam.theTopol->isItEdgePixelInX(maxPixelRow));
0447 bool edgey =
0448 (theDetParam.theTopol->isItEdgePixelInY(minPixelCol) || theDetParam.theTopol->isItEdgePixelInY(maxPixelCol));
0449
0450 if (theClusterParam.ierr != 0) {
0451
0452
0453
0454
0455
0456 if (!GeomDetEnumerators::isTrackerPixel(theDetParam.thePart))
0457 throw cms::Exception("PixelCPETemplateReco::localPosition :") << "A non-pixel detector type in here?";
0458
0459
0460 if (GeomDetEnumerators::isBarrel(theDetParam.thePart)) {
0461 xerr = 55.0f * micronsToCm;
0462 yerr = 36.0f * micronsToCm;
0463 } else {
0464 xerr = 42.0f * micronsToCm;
0465 yerr = 39.0f * micronsToCm;
0466 }
0467
0468
0469
0470
0471
0472 } else if (edgex || edgey) {
0473
0474 if (edgex && !edgey) {
0475 xerr = xEdgeXError_ * micronsToCm;
0476 yerr = xEdgeYError_ * micronsToCm;
0477 } else if (!edgex && edgey) {
0478 xerr = yEdgeXError_ * micronsToCm;
0479 yerr = yEdgeYError_ * micronsToCm;
0480 } else if (edgex && edgey) {
0481 xerr = bothEdgeXError_ * micronsToCm;
0482 yerr = bothEdgeYError_ * micronsToCm;
0483 } else {
0484 throw cms::Exception(" PixelCPETemplateReco::localError: Something wrong with pixel edge flag !!!");
0485 }
0486
0487
0488
0489 } else {
0490
0491
0492
0493 xerr = theClusterParam.templSigmaX_ * micronsToCm;
0494 yerr = theClusterParam.templSigmaY_ * micronsToCm;
0495
0496
0497
0498
0499
0500
0501 }
0502
0503 if (theVerboseLevel > 9) {
0504 LogDebug("PixelCPETemplateReco") << " Sizex = " << theClusterParam.theCluster->sizeX()
0505 << " Sizey = " << theClusterParam.theCluster->sizeY() << " Edgex = " << edgex
0506 << " Edgey = " << edgey << " ErrX = " << xerr << " ErrY = " << yerr;
0507 }
0508
0509 }
0510
0511 if (!(xerr > 0.0f))
0512 throw cms::Exception("PixelCPETemplateReco::localError")
0513 << "\nERROR: Negative pixel error xerr = " << xerr << "\n\n";
0514
0515 if (!(yerr > 0.0f))
0516 throw cms::Exception("PixelCPETemplateReco::localError")
0517 << "\nERROR: Negative pixel error yerr = " << yerr << "\n\n";
0518
0519
0520
0521
0522
0523
0524
0525 return LocalError(xerr * xerr, 0, yerr * yerr);
0526 }
0527
0528 void PixelCPETemplateReco::fillPSetDescription(edm::ParameterSetDescription& desc) {
0529 desc.add<int>("barrelTemplateID", 0);
0530 desc.add<int>("forwardTemplateID", 0);
0531 desc.add<int>("directoryWithTemplates", 0);
0532 desc.add<int>("speed", -2);
0533 desc.add<bool>("UseClusterSplitter", false);
0534 desc.add<bool>("GoodEdgeAlgo", false);
0535 }