Warning, /RecoLocalCalo/HGCalRecProducers/plugins/HGCalCellPositionsKernelImpl.cu is written in an unsupported language. File is not indexed.
0001 #include <cuda.h>
0002 #include <cuda_runtime.h>
0003 #include <inttypes.h>
0004 #include "DataFormats/ForwardDetId/interface/HGCalDetId.h"
0005 #include "RecoLocalCalo/HGCalRecProducers/plugins/HGCalCellPositionsKernelImpl.cuh"
0006
0007 __global__ void fill_positions_from_detids(
0008 const hgcal_conditions::HeterogeneousHEFCellPositionsConditionsESProduct* conds) {
0009 unsigned int tid = blockDim.x * blockIdx.x + threadIdx.x;
0010
0011 for (unsigned int i = tid; i < conds->nelems_posmap; i += blockDim.x * gridDim.x) {
0012 HeterogeneousHGCSiliconDetId did(conds->posmap.detid[i]);
0013 const float cU = static_cast<float>(did.cellU());
0014 const float cV = static_cast<float>(did.cellV());
0015 const float wU = static_cast<float>(did.waferU());
0016 const float wV = static_cast<float>(did.waferV());
0017 const float ncells = static_cast<float>(did.nCellsSide());
0018 const int32_t layer = did.layer();
0019
0020 //based on `std::pair<float, float> HGCalDDDConstants::locateCell(const HGCSiliconDetId&, bool)
0021 const float r_x2 = conds->posmap.waferSize + conds->posmap.sensorSeparation;
0022 const float r = 0.5f * r_x2;
0023 const float sqrt3 = __fsqrt_rn(3.f);
0024 const float rsqrt3 = __frsqrt_rn(3.f); //rsqrt: 1 / sqrt
0025 const float R = r_x2 * rsqrt3;
0026 const float n2 = ncells / 2.f;
0027 const float yoff_abs = rsqrt3 * r_x2;
0028 const float yoff = (layer % 2 == 1) ? yoff_abs : -1.f * yoff_abs; //CHANGE according to Sunanda's reply
0029 float xpos = (-2.f * wU + wV) * r;
0030 float ypos = yoff + (1.5f * wV * R);
0031 const float R1 = __fdividef(conds->posmap.waferSize, 3.f * ncells);
0032 const float r1_x2 = R1 * sqrt3;
0033 xpos += (1.5f * (cV - ncells) + 1.f) * R1;
0034 ypos += (cU - 0.5f * cV - n2) * r1_x2;
0035 conds->posmap.x[i] =
0036 xpos; // times side; multiply by -1 if one wants to obtain the position from the opposite endcap. CAREFUL WITH LATER DETECTOR ALIGNMENT!!!
0037 conds->posmap.y[i] = ypos;
0038 }
0039 }
0040
0041 __global__ void print_positions_from_detids(
0042 const hgcal_conditions::HeterogeneousHEFCellPositionsConditionsESProduct* conds) {
0043 unsigned int tid = blockDim.x * blockIdx.x + threadIdx.x;
0044
0045 for (unsigned int i = tid; i < conds->nelems_posmap; i += blockDim.x * gridDim.x) {
0046 HeterogeneousHGCSiliconDetId did(conds->posmap.detid[i]);
0047 const int32_t layer = did.layer();
0048 float posz = conds->posmap.zLayer[layer - 1];
0049 printf("PosX: %lf\t PosY: %lf\t Posz: %lf\n", conds->posmap.x[i], conds->posmap.y[i], posz);
0050 }
0051 }
0052
0053 //eventually this can also be written in parallel
0054 __device__ unsigned map_cell_index(const float& cu, const float& cv, const unsigned& ncells_side) {
0055 unsigned counter = 0;
0056 //left side of wafer
0057 for (int cellUmax = ncells_side, icellV = 0; cellUmax < 2 * ncells_side && icellV < ncells_side;
0058 ++cellUmax, ++icellV) {
0059 for (int icellU = 0; icellU <= cellUmax; ++icellU) {
0060 if (cu == icellU and cv == icellV)
0061 return counter;
0062 else
0063 counter += 1;
0064 }
0065 }
0066 //right side of wafer
0067 for (int cellUmin = 1, icellV = ncells_side; cellUmin <= ncells_side && icellV < 2 * ncells_side;
0068 ++cellUmin, ++icellV) {
0069 for (int icellU = cellUmin; icellU < 2 * ncells_side; ++icellU) {
0070 if (cu == icellU and cv == icellV)
0071 return counter;
0072 else
0073 counter += 1;
0074 }
0075 }
0076 printf("ERROR: The cell was not found!");
0077 return 99;
0078 }
0079
0080 //returns the index of the positions of a specific cell
0081 //performs several geometry-related shifts, and adds them at the end:
0082 // 1) number of cells up to the layer being inspected
0083 // 2) number of cells up to the waferUchunk in question, only in the layer being inspected
0084 // 3) number of cells up to the waferV in question, only in the layer and waferUchunk being inspected
0085 // 4) cell index within this layer, waferUchunk and waferV
0086 //Note: a 'waferUchunk' represents the first dimension of a 2D squared grid of wafers, and includes multiple waferV
0087 __device__ unsigned hash_function(const int32_t& l,
0088 const int32_t& wU,
0089 const int32_t& wV,
0090 const int32_t& cu,
0091 const int32_t& cv,
0092 const int32_t& ncells_side,
0093 const hgcal_conditions::HeterogeneousHEFCellPositionsConditionsESProduct* conds) {
0094 const unsigned thislayer = l - conds->posmap.firstLayer;
0095 const unsigned thisUwafer = wU - conds->posmap.waferMin;
0096 const unsigned thisVwafer = wV - conds->posmap.waferMin;
0097 const unsigned nwafers1D = conds->posmap.waferMax - conds->posmap.waferMin;
0098
0099 //layer shift in terms of cell number
0100 unsigned ncells_up_to_thislayer = 0;
0101 for (unsigned q = 0; q < thislayer; ++q)
0102 ncells_up_to_thislayer += conds->posmap.nCellsLayer[q];
0103
0104 //waferU shift in terms of cell number
0105 unsigned ncells_up_to_thisUwafer = 0;
0106 unsigned nwaferUchunks_up_to_this_layer = thislayer * nwafers1D;
0107 for (unsigned q = 0; q < thisUwafer; ++q)
0108 ncells_up_to_thisUwafer += conds->posmap.nCellsWaferUChunk[nwaferUchunks_up_to_this_layer + q];
0109
0110 //waferV shift in terms of cell number
0111 unsigned ncells_up_to_thisVwafer = 0;
0112 const unsigned nwafers_up_to_thisLayer = thislayer * nwafers1D * nwafers1D;
0113 const unsigned nwafers_up_to_thisUwafer = thisUwafer * nwafers1D;
0114 for (unsigned q = 0; q < thisVwafer; ++q)
0115 ncells_up_to_thisVwafer += conds->posmap.nCellsHexagon[nwafers_up_to_thisLayer + nwafers_up_to_thisUwafer + q];
0116
0117 //cell shift in terms of cell number
0118 const unsigned cell_shift = map_cell_index(cu, cv, ncells_side);
0119 const unsigned shift_total = ncells_up_to_thislayer + ncells_up_to_thisUwafer + ncells_up_to_thisVwafer + cell_shift;
0120 return shift_total;
0121 }
0122
0123 __global__ void test(uint32_t detid_test,
0124 const hgcal_conditions::HeterogeneousHEFCellPositionsConditionsESProduct* conds) {
0125 unsigned int tid = blockDim.x * blockIdx.x + threadIdx.x;
0126
0127 if (tid == 0) {
0128 //printf("Nelems: %u\n", static_cast<unsigned>(conds->nelems_posmap));
0129 for (unsigned i = 0; i < 1; ++i) {
0130 HeterogeneousHGCSiliconDetId did(detid_test); // 2416969935, 2552165379, ...
0131 const int32_t cU = did.cellU();
0132 const int32_t cV = did.cellV();
0133 const int32_t wU = did.waferU();
0134 const int32_t wV = did.waferV();
0135 const int32_t ncs = did.nCellsSide();
0136
0137 const int32_t layer = abs(did.layer()); //remove abs in case both endcaps are considered for x and y
0138 const unsigned shift = hash_function(layer, wU, wV, cU, cV, ncs, conds);
0139 //printf("id: cu: %d, cv: %d, wu: %d, wv: %d, ncells: %d, layer: %d\n", cU, cV, wU, wV, ncs, layer);
0140 printf("id: %u | shift: %u | x: %lf y: %lf\n",
0141 conds->posmap.detid[shift],
0142 shift,
0143 conds->posmap.x[shift],
0144 conds->posmap.y[shift]);
0145 }
0146 }
0147 }