File indexing completed on 2024-11-14 04:15:50
0001 #include <alpaka/alpaka.hpp>
0002
0003 #include "CondFormats/SiPixelTransient/interface/SiPixelGenError.h"
0004 #include "DataFormats/GeometrySurface/interface/SOARotation.h"
0005 #include "DataFormats/SiPixelClusterSoA/interface/ClusteringConstants.h"
0006 #include "DataFormats/TrackingRecHitSoA/interface/SiPixelHitStatus.h"
0007 #include "Geometry/CommonTopologies/interface/SimplePixelTopology.h"
0008 #include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h"
0009 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0010 #include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
0011 #include "RecoLocalTracker/SiPixelRecHits/interface/PixelCPEFastParamsHost.h"
0012
0013
0014
0015
0016 template <typename TrackerTraits>
0017 PixelCPEFastParamsHost<TrackerTraits>::PixelCPEFastParamsHost(edm::ParameterSet const& conf,
0018 const MagneticField* mag,
0019 const TrackerGeometry& geom,
0020 const TrackerTopology& ttopo,
0021 const SiPixelLorentzAngle* lorentzAngle,
0022 const SiPixelGenErrorDBObject* genErrorDBObject,
0023 const SiPixelLorentzAngle* lorentzAngleWidth)
0024 : PixelCPEGenericBase(conf, mag, geom, ttopo, lorentzAngle, genErrorDBObject, lorentzAngleWidth),
0025 buffer_(cms::alpakatools::make_host_buffer<pixelCPEforDevice::ParamsOnDeviceT<TrackerTraits>>()) {
0026
0027 if (useErrorsFromTemplates_) {
0028 if (!SiPixelGenError::pushfile(*genErrorDBObject_, this->thePixelGenError_))
0029 throw cms::Exception("InvalidCalibrationLoaded")
0030 << "ERROR: GenErrors not filled correctly. Check the sqlite file. Using SiPixelTemplateDBObject version "
0031 << (*genErrorDBObject_).version();
0032 }
0033
0034 fillParamsForDevice();
0035 }
0036
0037 template <typename TrackerTraits>
0038 void PixelCPEFastParamsHost<TrackerTraits>::fillParamsForDevice() {
0039
0040
0041
0042
0043 buffer_->commonParams().theThicknessB = m_DetParams.front().theThickness;
0044 buffer_->commonParams().theThicknessE = m_DetParams.back().theThickness;
0045 buffer_->commonParams().numberOfLaddersInBarrel = TrackerTraits::numberOfLaddersInBarrel;
0046
0047 LogDebug("PixelCPEFastParamsHost") << "thickness " << buffer_->commonParams().theThicknessB << ' '
0048 << buffer_->commonParams().theThicknessE;
0049
0050
0051 memset(&buffer_->averageGeometry(), 0, sizeof(pixelTopology::AverageGeometryT<TrackerTraits>));
0052
0053 memset(&buffer_->layerGeometry(), 0, sizeof(pixelCPEforDevice::LayerGeometryT<TrackerTraits>));
0054
0055 uint32_t nLayers = 0;
0056 uint32_t oldLayer = 0;
0057 uint32_t oldLadder = 0;
0058 float rl = 0;
0059 float zl = 0;
0060 float miz = 500, mxz = 0;
0061 float pl = 0;
0062 int nl = 0;
0063
0064 assert(m_DetParams.size() <= TrackerTraits::numberOfModules);
0065
0066 for (auto i = 0U; i < m_DetParams.size(); ++i) {
0067 auto& p = m_DetParams[i];
0068 auto& g = buffer_->detParams(i);
0069
0070 g.nRowsRoc = p.theDet->specificTopology().rowsperroc();
0071 g.nColsRoc = p.theDet->specificTopology().colsperroc();
0072 g.nRows = p.theDet->specificTopology().rocsX() * g.nRowsRoc;
0073 g.nCols = p.theDet->specificTopology().rocsY() * g.nColsRoc;
0074
0075 g.numPixsInModule = g.nRows * g.nCols;
0076
0077 assert(p.theDet->index() == int(i));
0078
0079 g.isBarrel = GeomDetEnumerators::isBarrel(p.thePart);
0080 g.isPosZ = p.theDet->surface().position().z() > 0;
0081 g.layer = ttopo_.layer(p.theDet->geographicalId());
0082 g.index = i;
0083 g.rawId = p.theDet->geographicalId();
0084 auto thickness = g.isBarrel ? buffer_->commonParams().theThicknessB : buffer_->commonParams().theThicknessE;
0085 assert(thickness == p.theThickness);
0086
0087 auto ladder = ttopo_.pxbLadder(p.theDet->geographicalId());
0088 if (oldLayer != g.layer) {
0089 oldLayer = g.layer;
0090 LogDebug("PixelCPEFastParamsHost") << "new layer at " << i << (g.isBarrel ? " B " : (g.isPosZ ? " E+ " : " E- "))
0091 << g.layer << " starting at " << g.rawId << '\n'
0092 << "old layer had " << nl << " ladders";
0093 nl = 0;
0094
0095 assert(nLayers <= TrackerTraits::numberOfLayers);
0096 buffer_->layerGeometry().layerStart[nLayers] = i;
0097 ++nLayers;
0098 }
0099 if (oldLadder != ladder) {
0100 oldLadder = ladder;
0101 LogDebug("PixelCPEFastParamsHost") << "new ladder at " << i
0102 << (g.isBarrel ? " B " : (g.isPosZ ? " E+ " : " E- ")) << ladder
0103 << " starting at " << g.rawId << '\n'
0104 << "old ladder ave z,r,p mz " << zl / 8.f << " " << rl / 8.f << " " << pl / 8.f
0105 << ' ' << miz << ' ' << mxz;
0106 rl = 0;
0107 zl = 0;
0108 pl = 0;
0109 miz = 500;
0110 mxz = 0;
0111 nl++;
0112 }
0113
0114 g.shiftX = 0.5f * p.lorentzShiftInCmX;
0115 g.shiftY = 0.5f * p.lorentzShiftInCmY;
0116 g.chargeWidthX = p.lorentzShiftInCmX * p.widthLAFractionX;
0117 g.chargeWidthY = p.lorentzShiftInCmY * p.widthLAFractionY;
0118
0119 g.x0 = p.theOrigin.x();
0120 g.y0 = p.theOrigin.y();
0121 g.z0 = p.theOrigin.z();
0122
0123 g.thePitchX = p.thePitchX;
0124 g.thePitchY = p.thePitchY;
0125
0126 auto vv = p.theDet->surface().position();
0127 auto rr = pixelCPEforDevice::Rotation(p.theDet->surface().rotation());
0128 g.frame = pixelCPEforDevice::Frame(vv.x(), vv.y(), vv.z(), rr);
0129
0130 zl += vv.z();
0131 miz = std::min(miz, std::abs(vv.z()));
0132 mxz = std::max(mxz, std::abs(vv.z()));
0133 rl += vv.perp();
0134 pl += vv.phi();
0135
0136
0137 ClusterParamGeneric cp;
0138
0139 cp.with_track_angle = false;
0140
0141 auto lape = p.theDet->localAlignmentError();
0142 if (lape.invalid())
0143 lape = LocalError();
0144
0145 g.apeXX = lape.xx();
0146 g.apeYY = lape.yy();
0147
0148 auto toMicron = [&](float x) { return std::min(511, int(x * 1.e4f + 0.5f)); };
0149
0150
0151 auto gvx = p.theOrigin.x() + 40.f * p.thePitchX;
0152 auto gvy = p.theOrigin.y();
0153 auto gvz = 1.f / p.theOrigin.z();
0154
0155
0156 {
0157
0158 cp.cotalpha = gvx * gvz;
0159 cp.cotbeta = gvy * gvz;
0160
0161 errorFromTemplates(p, cp, 20000.);
0162 }
0163
0164 #ifdef EDM_ML_DEBUG
0165 auto m = 10000.f;
0166 for (float qclus = 15000; qclus < 35000; qclus += 15000) {
0167 errorFromTemplates(p, cp, qclus);
0168 LogDebug("PixelCPEFastParamsHost") << i << ' ' << qclus << ' ' << cp.pixmx << ' ' << m * cp.sigmax << ' '
0169 << m * cp.sx1 << ' ' << m * cp.sx2 << ' ' << m * cp.sigmay << ' ' << m * cp.sy1
0170 << ' ' << m * cp.sy2;
0171 }
0172 LogDebug("PixelCPEFastParamsHost") << i << ' ' << m * std::sqrt(lape.xx()) << ' ' << m * std::sqrt(lape.yy());
0173 #endif
0174
0175 g.pixmx = std::max(0, cp.pixmx);
0176 g.sx2 = toMicron(cp.sx2);
0177 g.sy1 = std::max(21, toMicron(cp.sy1));
0178 g.sy2 = std::max(55, toMicron(cp.sy2));
0179
0180
0181
0182
0183 float moduleOffsetX = -(0.5f * float(g.nRows) + TrackerTraits::bigPixXCorrection);
0184 auto const xoff = moduleOffsetX * g.thePitchX;
0185
0186 for (int ix = 0; ix < pixelCPEforDevice::kNumErrorBins; ++ix) {
0187 auto x = xoff * (1.f - (0.5f + float(ix)) / 8.f);
0188 auto gvx = p.theOrigin.x() - x;
0189 auto gvy = p.theOrigin.y();
0190 auto gvz = 1.f / p.theOrigin.z();
0191 cp.cotbeta = gvy * gvz;
0192 cp.cotalpha = gvx * gvz;
0193 errorFromTemplates(p, cp, 20000.f);
0194 g.sigmax[ix] = toMicron(cp.sigmax);
0195 g.sigmax1[ix] = toMicron(cp.sx1);
0196 LogDebug("PixelCPEFastParamsHost") << "sigmax vs x " << i << ' ' << x << ' ' << cp.cotalpha << ' '
0197 << int(g.sigmax[ix]) << ' ' << int(g.sigmax1[ix]) << ' ' << 10000.f * cp.sigmay
0198 << std::endl;
0199 }
0200 #ifdef EDM_ML_DEBUG
0201
0202
0203 float moduleOffsetY = 0.5f * float(g.nCols) + TrackerTraits::bigPixYCorrection;
0204 auto const yoff = -moduleOffsetY * p.thePitchY;
0205
0206 for (int ix = 0; ix < pixelCPEforDevice::kNumErrorBins; ++ix) {
0207 auto y = yoff * (1.f - (0.5f + float(ix)) / 8.f);
0208 auto gvx = p.theOrigin.x() + 40.f * p.thePitchY;
0209 auto gvy = p.theOrigin.y() - y;
0210 auto gvz = 1.f / p.theOrigin.z();
0211 cp.cotbeta = gvy * gvz;
0212 cp.cotalpha = gvx * gvz;
0213 errorFromTemplates(p, cp, 20000.f);
0214 LogDebug("PixelCPEFastParamsHost") << "sigmay vs y " << i << ' ' << y << ' ' << cp.cotbeta << ' '
0215 << 10000.f * cp.sigmay << std::endl;
0216 }
0217 #endif
0218
0219
0220 cp.cotalpha = gvx * gvz;
0221 cp.cotbeta = gvy * gvz;
0222 auto aveCB = cp.cotbeta;
0223
0224
0225 int qbin = pixelCPEforDevice::kGenErrorQBins;
0226 int k = 0;
0227 int qClusIncrement = 100;
0228 for (int qclus = 100; k < pixelCPEforDevice::kGenErrorQBins; qclus += qClusIncrement) {
0229 errorFromTemplates(p, cp, qclus);
0230 if (cp.qBin_ == qbin) {
0231 continue;
0232 }
0233
0234
0235 if (cp.qBin_ < qbin - 1) {
0236
0237
0238
0239 qbin += 1;
0240 qclus -= qClusIncrement;
0241 errorFromTemplates(p, cp, qclus);
0242 g.xfact[k] = cp.sigmax;
0243 g.yfact[k] = cp.sigmay;
0244 g.minCh[k++] = qclus / 2;
0245 continue;
0246 }
0247
0248 qbin = cp.qBin_;
0249
0250
0251 if (qbin < pixelCPEforDevice::kGenErrorQBins) {
0252 qClusIncrement = 1000;
0253 }
0254
0255 g.xfact[k] = cp.sigmax;
0256 g.yfact[k] = cp.sigmay;
0257 g.minCh[k++] = qclus;
0258 #ifdef EDM_ML_DEBUG
0259 LogDebug("PixelCPEFastParamsHost") << i << ' ' << g.rawId << ' ' << cp.cotalpha << ' ' << qclus << ' ' << cp.qBin_
0260 << ' ' << cp.pixmx << ' ' << m * cp.sigmax << ' ' << m * cp.sx1 << ' '
0261 << m * cp.sx2 << ' ' << m * cp.sigmay << ' ' << m * cp.sy1 << ' ' << m * cp.sy2
0262 << std::endl;
0263 #endif
0264 }
0265
0266 assert(k <= pixelCPEforDevice::kGenErrorQBins);
0267
0268
0269 for (int kk = k; kk < pixelCPEforDevice::kGenErrorQBins; ++kk) {
0270 g.xfact[kk] = g.xfact[k - 1];
0271 g.yfact[kk] = g.yfact[k - 1];
0272 g.minCh[kk] = g.minCh[k - 1];
0273 }
0274 auto detx = 1.f / g.xfact[0];
0275 auto dety = 1.f / g.yfact[0];
0276 for (int kk = 0; kk < pixelCPEforDevice::kGenErrorQBins; ++kk) {
0277 g.xfact[kk] *= detx;
0278 g.yfact[kk] *= dety;
0279 }
0280
0281 float ys = 8.f - 4.f;
0282
0283
0284 for (int iy = 0; iy < pixelCPEforDevice::kNumErrorBins; ++iy) {
0285 ys += 1.f;
0286 if (pixelCPEforDevice::kNumErrorBins - 1 == iy)
0287 ys += 8.f;
0288
0289 cp.cotbeta = std::copysign(ys * (g.thePitchY / (8.f * thickness)), aveCB);
0290 errorFromTemplates(p, cp, 20000.f);
0291 g.sigmay[iy] = toMicron(cp.sigmay);
0292 LogDebug("PixelCPEFastParamsHost") << "sigmax/sigmay " << i << ' ' << (ys + 4.f) / 8.f << ' ' << cp.cotalpha
0293 << '/' << cp.cotbeta << ' ' << 10000.f * cp.sigmax << '/' << int(g.sigmay[iy])
0294 << std::endl;
0295 }
0296 }
0297
0298
0299 buffer_->layerGeometry().layerStart[nLayers] = m_DetParams.size();
0300
0301 constexpr int numberOfModulesInLadder = TrackerTraits::numberOfModulesInLadder;
0302 constexpr int numberOfLaddersInBarrel = TrackerTraits::numberOfLaddersInBarrel;
0303 constexpr int numberOfModulesInBarrel = TrackerTraits::numberOfModulesInBarrel;
0304
0305 constexpr float ladderFactor = 1.f / float(numberOfModulesInLadder);
0306
0307 constexpr int firstEndcapPos = TrackerTraits::firstEndcapPos;
0308 constexpr int firstEndcapNeg = TrackerTraits::firstEndcapNeg;
0309
0310
0311
0312 auto& aveGeom = buffer_->averageGeometry();
0313 int il = 0;
0314 for (int im = 0, nm = numberOfModulesInBarrel; im < nm; ++im) {
0315 auto const& g = buffer_->detParams(im);
0316 il = im / numberOfModulesInLadder;
0317 assert(il < int(numberOfLaddersInBarrel));
0318 auto z = g.frame.z();
0319 aveGeom.ladderZ[il] += ladderFactor * z;
0320 aveGeom.ladderMinZ[il] = std::min(aveGeom.ladderMinZ[il], z);
0321 aveGeom.ladderMaxZ[il] = std::max(aveGeom.ladderMaxZ[il], z);
0322 aveGeom.ladderX[il] += ladderFactor * g.frame.x();
0323 aveGeom.ladderY[il] += ladderFactor * g.frame.y();
0324 aveGeom.ladderR[il] += ladderFactor * sqrt(g.frame.x() * g.frame.x() + g.frame.y() * g.frame.y());
0325 }
0326 assert(il + 1 == int(numberOfLaddersInBarrel));
0327
0328 constexpr float moduleLength = TrackerTraits::moduleLength;
0329 constexpr float module_tolerance = 0.2f;
0330 for (int il = 0, nl = numberOfLaddersInBarrel; il < nl; ++il) {
0331 aveGeom.ladderMinZ[il] -= (0.5f * moduleLength - module_tolerance);
0332 aveGeom.ladderMaxZ[il] += (0.5f * moduleLength - module_tolerance);
0333 }
0334
0335
0336 for (auto im = TrackerTraits::layerStart[firstEndcapPos]; im < TrackerTraits::layerStart[firstEndcapPos + 1]; ++im) {
0337 auto const& g = buffer_->detParams(im);
0338 aveGeom.endCapZ[0] = std::max(aveGeom.endCapZ[0], g.frame.z());
0339 }
0340 for (auto im = TrackerTraits::layerStart[firstEndcapNeg]; im < TrackerTraits::layerStart[firstEndcapNeg + 1]; ++im) {
0341 auto const& g = buffer_->detParams(im);
0342 aveGeom.endCapZ[1] = std::min(aveGeom.endCapZ[1], g.frame.z());
0343 }
0344
0345 aveGeom.endCapZ[0] -= TrackerTraits::endcapCorrection;
0346 aveGeom.endCapZ[1] += TrackerTraits::endcapCorrection;
0347 #ifdef EDM_ML_DEBUG
0348 for (int jl = 0, nl = numberOfLaddersInBarrel; jl < nl; ++jl) {
0349 LogDebug("PixelCPEFastParamsHost") << jl << ':' << aveGeom.ladderR[jl] << '/'
0350 << std::sqrt(aveGeom.ladderX[jl] * aveGeom.ladderX[jl] +
0351 aveGeom.ladderY[jl] * aveGeom.ladderY[jl])
0352 << ',' << aveGeom.ladderZ[jl] << ',' << aveGeom.ladderMinZ[jl] << ','
0353 << aveGeom.ladderMaxZ[jl] << '\n';
0354 }
0355 LogDebug("PixelCPEFastParamsHost") << aveGeom.endCapZ[0] << ' ' << aveGeom.endCapZ[1];
0356 #endif
0357
0358
0359 memcpy(buffer_->layerGeometry().layer,
0360 pixelTopology::layer<TrackerTraits>.data(),
0361 pixelTopology::layer<TrackerTraits>.size());
0362 buffer_->layerGeometry().maxModuleStride = pixelTopology::maxModuleStride<TrackerTraits>;
0363 }
0364
0365 template <typename TrackerTraits>
0366 void PixelCPEFastParamsHost<TrackerTraits>::errorFromTemplates(DetParam const& theDetParam,
0367 ClusterParamGeneric& theClusterParam,
0368 float qclus) const {
0369 float locBz = theDetParam.bz;
0370 float locBx = theDetParam.bx;
0371 LogDebug("PixelCPEFastParamsHost") << "PixelCPEFastParamsHost::localPosition(...) : locBz = " << locBz;
0372
0373 theClusterParam.pixmx = std::numeric_limits<int>::max();
0374
0375 theClusterParam.sigmay = -999.9;
0376 theClusterParam.sigmax = -999.9;
0377 theClusterParam.sy1 = -999.9;
0378 theClusterParam.sy2 = -999.9;
0379 theClusterParam.sx1 = -999.9;
0380 theClusterParam.sx2 = -999.9;
0381
0382 float dummy;
0383
0384 SiPixelGenError gtempl(this->thePixelGenError_);
0385 int gtemplID = theDetParam.detTemplateId;
0386
0387 theClusterParam.qBin_ = gtempl.qbin(gtemplID,
0388 theClusterParam.cotalpha,
0389 theClusterParam.cotbeta,
0390 locBz,
0391 locBx,
0392 qclus,
0393 false,
0394 theClusterParam.pixmx,
0395 theClusterParam.sigmay,
0396 dummy,
0397 theClusterParam.sigmax,
0398 dummy,
0399 theClusterParam.sy1,
0400 dummy,
0401 theClusterParam.sy2,
0402 dummy,
0403 theClusterParam.sx1,
0404 dummy,
0405 theClusterParam.sx2,
0406 dummy);
0407
0408 theClusterParam.sigmax = theClusterParam.sigmax * pixelCPEforDevice::micronsToCm;
0409 theClusterParam.sx1 = theClusterParam.sx1 * pixelCPEforDevice::micronsToCm;
0410 theClusterParam.sx2 = theClusterParam.sx2 * pixelCPEforDevice::micronsToCm;
0411
0412 theClusterParam.sigmay = theClusterParam.sigmay * pixelCPEforDevice::micronsToCm;
0413 theClusterParam.sy1 = theClusterParam.sy1 * pixelCPEforDevice::micronsToCm;
0414 theClusterParam.sy2 = theClusterParam.sy2 * pixelCPEforDevice::micronsToCm;
0415 }
0416
0417
0418
0419
0420
0421
0422 template <typename TrackerTraits>
0423 LocalPoint PixelCPEFastParamsHost<TrackerTraits>::localPosition(DetParam const& theDetParam,
0424 ClusterParam& theClusterParamBase) const {
0425 ClusterParamGeneric& theClusterParam = static_cast<ClusterParamGeneric&>(theClusterParamBase);
0426
0427 if (useErrorsFromTemplates_) {
0428 errorFromTemplates(theDetParam, theClusterParam, theClusterParam.theCluster->charge());
0429 } else {
0430 theClusterParam.qBin_ = 0;
0431 }
0432
0433 int q_f_X;
0434 int q_l_X;
0435 int q_f_Y;
0436 int q_l_Y;
0437 collect_edge_charges(theClusterParam, q_f_X, q_l_X, q_f_Y, q_l_Y, useErrorsFromTemplates_ && truncatePixelCharge_);
0438
0439
0440 pixelCPEforDevice::ClusParams cp;
0441
0442 cp.minRow[0] = theClusterParam.theCluster->minPixelRow();
0443 cp.maxRow[0] = theClusterParam.theCluster->maxPixelRow();
0444 cp.minCol[0] = theClusterParam.theCluster->minPixelCol();
0445 cp.maxCol[0] = theClusterParam.theCluster->maxPixelCol();
0446
0447 cp.q_f_X[0] = q_f_X;
0448 cp.q_l_X[0] = q_l_X;
0449 cp.q_f_Y[0] = q_f_Y;
0450 cp.q_l_Y[0] = q_l_Y;
0451
0452 cp.charge[0] = theClusterParam.theCluster->charge();
0453
0454 auto ind = theDetParam.theDet->index();
0455 pixelCPEforDevice::position<TrackerTraits>(buffer_->commonParams(), buffer_->detParams(ind), cp, 0);
0456 auto xPos = cp.xpos[0];
0457 auto yPos = cp.ypos[0];
0458
0459
0460 pixelCPEforDevice::errorFromDB<TrackerTraits>(buffer_->commonParams(), buffer_->detParams(ind), cp, 0);
0461 theClusterParam.sigmax = cp.xerr[0];
0462 theClusterParam.sigmay = cp.yerr[0];
0463
0464 LogDebug("PixelCPEFastParamsHost") << " in PixelCPEFastParamsHost:localPosition - pos = " << xPos << " " << yPos
0465 << " size " << cp.maxRow[0] - cp.minRow[0] << ' ' << cp.maxCol[0] - cp.minCol[0];
0466
0467
0468 LocalPoint pos_in_local(xPos, yPos);
0469 return pos_in_local;
0470 }
0471
0472
0473
0474
0475
0476
0477 template <typename TrackerTraits>
0478 LocalError PixelCPEFastParamsHost<TrackerTraits>::localError(DetParam const& theDetParam,
0479 ClusterParam& theClusterParamBase) const {
0480 ClusterParamGeneric& theClusterParam = static_cast<ClusterParamGeneric&>(theClusterParamBase);
0481
0482 auto xerr = theClusterParam.sigmax;
0483 auto yerr = theClusterParam.sigmay;
0484
0485 LogDebug("PixelCPEFastParamsHost") << " errors " << xerr << " " << yerr;
0486
0487 auto xerr_sq = xerr * xerr;
0488 auto yerr_sq = yerr * yerr;
0489
0490 return LocalError(xerr_sq, 0, yerr_sq);
0491 }
0492
0493 template <typename TrackerTraits>
0494 void PixelCPEFastParamsHost<TrackerTraits>::fillPSetDescription(edm::ParameterSetDescription& desc) {
0495
0496 PixelCPEGenericBase::fillPSetDescription(desc);
0497 }
0498
0499 template class PixelCPEFastParamsHost<pixelTopology::Phase1>;
0500 template class PixelCPEFastParamsHost<pixelTopology::Phase2>;
0501 template class PixelCPEFastParamsHost<pixelTopology::HIonPhase1>;