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