File indexing completed on 2024-09-04 04:35:15
0001 #include "L1Trigger/DTTriggerPhase2/interface/GlobalCoordsObtainer.h"
0002
0003 using namespace edm;
0004 using namespace cmsdt;
0005 using namespace std;
0006
0007
0008
0009
0010 GlobalCoordsObtainer::GlobalCoordsObtainer(const ParameterSet& pset) {
0011 global_coords_filename_ = pset.getParameter<edm::FileInPath>("global_coords_filename");
0012 std::ifstream ifin3(global_coords_filename_.fullPath());
0013
0014 if (ifin3.fail()) {
0015 throw cms::Exception("Missing Input File")
0016 << "GlobalCoordsObtainer::GlobalCoordsObtainer() - Cannot find " << global_coords_filename_.fullPath();
0017 }
0018
0019 int wh, st, se, sl;
0020 double perp, x_phi0;
0021 std::string line;
0022
0023 global_constant_per_sl sl1_constants;
0024 global_constant_per_sl sl3_constants;
0025
0026 while (ifin3.good()) {
0027 ifin3 >> wh >> st >> se >> sl >> perp >> x_phi0;
0028
0029 if (sl == 1) {
0030 sl1_constants.perp = perp;
0031 sl1_constants.x_phi0 = x_phi0;
0032 } else {
0033 sl3_constants.perp = perp;
0034 sl3_constants.x_phi0 = x_phi0;
0035
0036 DTChamberId ChId(wh, st, se);
0037 global_constants.push_back({ChId.rawId(), sl1_constants, sl3_constants});
0038 }
0039 }
0040
0041 int maxdrift;
0042 maxdrift_filename_ = pset.getParameter<edm::FileInPath>("maxdrift_filename");
0043 std::ifstream ifind(maxdrift_filename_.fullPath());
0044 if (ifind.fail()) {
0045 throw cms::Exception("Missing Input File")
0046 << "MPSLFilter::MPSLFilter() - Cannot find " << maxdrift_filename_.fullPath();
0047 }
0048 while (ifind.good()) {
0049 ifind >> wh >> st >> se >> maxdrift;
0050 maxdriftinfo_[wh][st][se] = maxdrift;
0051 }
0052 }
0053
0054 GlobalCoordsObtainer::~GlobalCoordsObtainer() {}
0055
0056 void GlobalCoordsObtainer::generate_luts() {
0057 for (auto& global_constant : global_constants) {
0058 int sgn = 1;
0059 DTChamberId ChId(global_constant.chid);
0060
0061 if (ChId.wheel() > 0 || (ChId.wheel() == 0 && ChId.sector() % 4 > 1)) {
0062 sgn = -1;
0063 }
0064
0065 max_drift_tdc = maxdriftinfo_[ChId.wheel() + 2][ChId.station() - 1][ChId.sector() - 1];
0066 int SEMICELL_IN_TDC_COUNTS = max_drift_tdc;
0067 int SL1_SEMICELL_OFFSET = 96;
0068
0069
0070 auto phi =
0071 calc_atan_lut(11,
0072 6,
0073 21. / SEMICELL_IN_TDC_COUNTS / ((global_constant.sl1.perp + global_constant.sl3.perp) / .2),
0074 (global_constant.sl1.x_phi0 - 2.1 * SL1_SEMICELL_OFFSET) /
0075 ((global_constant.sl1.perp + global_constant.sl3.perp) / 2),
0076 1. / std::pow(2, 17),
0077 9,
0078 4,
0079 11,
0080 21,
0081 sgn);
0082
0083 auto phib =
0084 calc_atan_lut(9, 5, 21. / SEMICELL_IN_TDC_COUNTS / (6.5 * 16), 0., 4. / std::pow(2, 13), 9, 3, 10, 16, sgn);
0085
0086 luts[global_constant.chid] = {phi, phib};
0087 }
0088 }
0089
0090 std::map<int, lut_value> GlobalCoordsObtainer::calc_atan_lut(int msb_num,
0091 int lsb_num,
0092 double in_res,
0093 double abscissa_0,
0094 double out_res,
0095 int a_extra_bits,
0096 int b_extra_bits,
0097 int a_size,
0098 int b_size,
0099 int sgn) {
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 long int a_min = -std::pow(2, (a_size - 1));
0115 long int a_max = std::pow(2, (a_size - 1)) - 1;
0116 long int b_min = -std::pow(2, (b_size - 1));
0117 long int b_max = std::pow(2, (b_size - 1)) - 1;
0118
0119 std::map<int, lut_value> lut;
0120
0121 for (long int x_msb = -(long int)std::pow(2, msb_num - 1); x_msb < (long int)std::pow(2, msb_num - 1); x_msb++) {
0122 int x1 = ((x_msb) << lsb_num);
0123 int x2 = ((x_msb + 1) << lsb_num) - 1;
0124
0125 double t1 = x1 * in_res - abscissa_0;
0126 double t2 = x2 * in_res - abscissa_0;
0127
0128 double phi1 = sgn * atan(t1);
0129 double phi2 = sgn * atan(t2);
0130
0131 double y1 = phi1 / out_res;
0132 double y2 = phi2 / out_res;
0133
0134
0135
0136 double a = (y2 - y1) / (x2 - x1);
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146 double t_max_err = sqrt(sgn * in_res / out_res / a - 1);
0147 if ((t1 + t2) < 0) {
0148 t_max_err *= -1;
0149 }
0150
0151 double x_max_err = (t_max_err + abscissa_0) / in_res;
0152 double phi_max_err = sgn * atan(t_max_err);
0153 double y_max_err = phi_max_err / out_res;
0154
0155
0156
0157
0158
0159
0160 double b = (y1 + y_max_err - a * (x_max_err - x1)) / 2;
0161
0162
0163
0164 b += 0.5;
0165
0166
0167 long int a_int = (long int)(round(a * (pow(2, a_extra_bits))));
0168 long int b_int = (long int)(round(b * (pow(2, b_extra_bits))));
0169
0170
0171 std::vector<long int> as = {a_min, a_int, a_max};
0172 std::vector<long int> bs = {b_min, b_int, b_max};
0173
0174 std::sort(as.begin(), as.end());
0175 std::sort(bs.begin(), bs.end());
0176
0177 a_int = as.at(1);
0178 b_int = bs.at(1);
0179
0180
0181
0182
0183
0184
0185 int index = to_two_comp(x_msb, msb_num);
0186 lut[index] = {a_int, b_int};
0187 }
0188 return lut;
0189 }
0190
0191 std::vector<double> GlobalCoordsObtainer::get_global_coordinates(uint32_t chid, int sl, int x, int tanpsi) {
0192
0193
0194
0195
0196 auto phi_lut = &luts[chid].phi;
0197 auto phib_lut = &luts[chid].phib;
0198
0199
0200 x = to_two_comp(x, X_SIZE);
0201 tanpsi = to_two_comp(tanpsi, TANPSI_SIZE);
0202
0203
0204
0205
0206
0207
0208
0209
0210 int x_msb = x >> (X_SIZE - PHI_LUT_ADDR_WIDTH);
0211 x_msb = from_two_comp(x_msb, PHI_LUT_ADDR_WIDTH);
0212
0213 int tanpsi_msb = tanpsi >> (TANPSI_SIZE - PHIB_LUT_ADDR_WIDTH);
0214 tanpsi_msb = from_two_comp(tanpsi_msb, PHIB_LUT_ADDR_WIDTH);
0215
0216
0217 int x_lsb = x & (int)(std::pow(2, (X_SIZE - PHI_LUT_ADDR_WIDTH)) - 1);
0218 int tanpsi_lsb = tanpsi & (int)(std::pow(2, (TANPSI_SIZE - PHIB_LUT_ADDR_WIDTH)) - 1);
0219
0220
0221 auto phi_lut_q = phi_lut->at(to_two_comp(x_msb, PHI_LUT_ADDR_WIDTH));
0222 auto phib_lut_q = phib_lut->at(to_two_comp(tanpsi_msb, PHIB_LUT_ADDR_WIDTH));
0223
0224
0225 auto phi_lut_a = phi_lut_q.a;
0226 auto phi_lut_b = phi_lut_q.b;
0227 auto phib_lut_a = phib_lut_q.a;
0228 auto phib_lut_b = phib_lut_q.b;
0229
0230
0231
0232
0233 int phi_uncut = (phi_lut_b << PHI_B_SHL_BITS) + x_lsb * phi_lut_a;
0234 int psi_uncut = (phib_lut_b << PHIB_B_SHL_BITS) + tanpsi_lsb * phib_lut_a;
0235
0236
0237 int phi = (phi_uncut >> PHI_MULT_SHR_BITS);
0238
0239
0240 int phib_uncut = psi_uncut - (phi_uncut >> (PHI_PHIB_RES_DIFF_BITS + PHI_MULT_SHR_BITS - PHIB_MULT_SHR_BITS));
0241 int phib = (phib_uncut >> PHIB_MULT_SHR_BITS);
0242
0243 double phi_f = (double)phi * PHI_SIZE;
0244 double phib_f = (double)phib * PHIB_SIZE;
0245
0246 return std::vector({phi_f, phib_f});
0247 }