File indexing completed on 2024-09-07 04:36:47
0001 #include "L1Trigger/DTTriggerPhase2/interface/MuonPathSLFitter.h"
0002 #include <cmath>
0003 #include <memory>
0004
0005 using namespace edm;
0006 using namespace std;
0007 using namespace cmsdt;
0008
0009
0010
0011 MuonPathSLFitter::MuonPathSLFitter(const ParameterSet &pset,
0012 edm::ConsumesCollector &iC,
0013 std::shared_ptr<GlobalCoordsObtainer> &globalcoordsobtainer)
0014 : MuonPathFitter(pset, iC, globalcoordsobtainer) {
0015 if (debug_)
0016 LogDebug("MuonPathSLFitter") << "MuonPathSLFitter: constructor";
0017
0018
0019 int rawId;
0020 double shift;
0021 shift_theta_filename_ = pset.getParameter<edm::FileInPath>("shift_theta_filename");
0022 std::ifstream ifin4(shift_theta_filename_.fullPath());
0023 if (ifin4.fail()) {
0024 throw cms::Exception("Missing Input File")
0025 << "MuonPathSLFitter::MuonPathSLFitter() - Cannot find " << shift_theta_filename_.fullPath();
0026 }
0027
0028 while (ifin4.good()) {
0029 ifin4 >> rawId >> shift;
0030 shiftthetainfo_[rawId] = shift;
0031 }
0032
0033
0034 sl1_filename_ = pset.getParameter<edm::FileInPath>("lut_sl1");
0035 sl2_filename_ = pset.getParameter<edm::FileInPath>("lut_sl2");
0036 sl3_filename_ = pset.getParameter<edm::FileInPath>("lut_sl3");
0037
0038 fillLuts();
0039
0040 setChi2Th(pset.getParameter<double>("chi2Th"));
0041 setTanPhiTh(pset.getParameter<double>("tanPhiTh"));
0042 }
0043
0044 MuonPathSLFitter::~MuonPathSLFitter() {
0045 if (debug_)
0046 LogDebug("MuonPathSLFitter") << "MuonPathSLFitter: destructor";
0047 }
0048
0049
0050
0051
0052 void MuonPathSLFitter::initialise(const edm::EventSetup &iEventSetup) {
0053 if (debug_)
0054 LogDebug("MuonPathSLFitter") << "MuonPathSLFitter::initialiase";
0055
0056 auto geom = iEventSetup.getHandle(dtGeomH);
0057 dtGeo_ = &(*geom);
0058 }
0059
0060 void MuonPathSLFitter::run(edm::Event &iEvent,
0061 const edm::EventSetup &iEventSetup,
0062 MuonPathPtrs &muonpaths,
0063 std::vector<lat_vector> &lateralities,
0064 std::vector<metaPrimitive> &metaPrimitives) {
0065 if (debug_)
0066 LogDebug("MuonPathSLFitter") << "MuonPathSLFitter: run";
0067
0068
0069
0070 if (!muonpaths.empty()) {
0071 auto muonpath = muonpaths[0];
0072 int rawId = muonpath->primitive(0)->cameraId();
0073 if (muonpath->primitive(0)->cameraId() == -1) {
0074 rawId = muonpath->primitive(1)->cameraId();
0075 }
0076 const DTLayerId dtLId(rawId);
0077 max_drift_tdc = maxdriftinfo_[dtLId.wheel() + 2][dtLId.station() - 1][dtLId.sector() - 1];
0078 }
0079
0080 for (size_t i = 0; i < muonpaths.size(); i++) {
0081 auto muonpath = muonpaths[i];
0082 auto lats = lateralities[i];
0083 analyze(muonpath, lats, metaPrimitives);
0084 }
0085 }
0086
0087 void MuonPathSLFitter::finish() {
0088 if (debug_)
0089 LogDebug("MuonPathSLFitter") << "MuonPathSLFitter: finish";
0090 };
0091
0092
0093
0094
0095
0096 void MuonPathSLFitter::analyze(MuonPathPtr &inMPath,
0097 lat_vector lat_combs,
0098 std::vector<cmsdt::metaPrimitive> &metaPrimitives) {
0099 auto sl = inMPath->primitive(0)->superLayerId();
0100
0101 int selected_lay = 1;
0102 if (inMPath->primitive(0)->cameraId() > 0)
0103 selected_lay = 0;
0104
0105 int dumLayId = inMPath->primitive(selected_lay)->cameraId();
0106 auto dtDumlayerId = DTLayerId(dumLayId);
0107 DTSuperLayerId MuonPathSLId(dtDumlayerId.wheel(), dtDumlayerId.station(), dtDumlayerId.sector(), sl + 1);
0108
0109 DTChamberId ChId(MuonPathSLId.wheel(), MuonPathSLId.station(), MuonPathSLId.sector());
0110
0111 DTSuperLayerId MuonPathSL1Id(dtDumlayerId.wheel(), dtDumlayerId.station(), dtDumlayerId.sector(), 1);
0112 DTSuperLayerId MuonPathSL2Id(dtDumlayerId.wheel(), dtDumlayerId.station(), dtDumlayerId.sector(), 2);
0113 DTSuperLayerId MuonPathSL3Id(dtDumlayerId.wheel(), dtDumlayerId.station(), dtDumlayerId.sector(), 3);
0114 DTWireId wireIdSL1(MuonPathSL1Id, 2, 1);
0115 DTWireId wireIdSL2(MuonPathSL2Id, 2, 1);
0116 DTWireId wireIdSL3(MuonPathSL3Id, 2, 1);
0117 auto sl_shift_cm = shiftinfo_[wireIdSL1.rawId()] - shiftinfo_[wireIdSL3.rawId()];
0118
0119 fit_common_in_t fit_common_in;
0120
0121
0122 fit_common_in.hits = {};
0123 fit_common_in.hits_valid = {};
0124
0125 int quality = 3;
0126 if (inMPath->missingLayer() != -1)
0127 quality = 1;
0128
0129 int minISL = 1;
0130 int maxISL = 3;
0131 if (sl < 1) {
0132 minISL = 0;
0133 maxISL = 2;
0134 }
0135
0136 for (int isl = minISL; isl < maxISL; isl++) {
0137 for (int i = 0; i < NUM_LAYERS; i++) {
0138 if (isl == sl && inMPath->missingLayer() != i) {
0139
0140 auto ti = inMPath->primitive(i)->tdcTimeStamp();
0141 if (ti != -1)
0142 ti = (int)round(((float)TIME_TO_TDC_COUNTS / (float)LHC_CLK_FREQ) * ti);
0143 auto wi = inMPath->primitive(i)->channelId();
0144 auto ly = inMPath->primitive(i)->layerId();
0145
0146
0147
0148
0149
0150 int wp_semicells = (wi - SL1_CELLS_OFFSET) * 2 + 1;
0151 if (ly % 2 == 1)
0152 wp_semicells -= 1;
0153 if (isl == 2)
0154 wp_semicells -= (int)round((sl_shift_cm * 10) / CELL_SEMILENGTH);
0155
0156 float wp_tdc = wp_semicells * max_drift_tdc;
0157 int wp = (int)((long int)(round(wp_tdc * std::pow(2, WIREPOS_WIDTH))) / (int)std::pow(2, WIREPOS_WIDTH));
0158 fit_common_in.hits.push_back({ti, wi, ly, wp});
0159
0160 if (inMPath->missingLayer() == i)
0161 fit_common_in.hits_valid.push_back(0);
0162 else
0163 fit_common_in.hits_valid.push_back(1);
0164 } else {
0165 fit_common_in.hits.push_back({-1, -1, -1, -1});
0166 fit_common_in.hits_valid.push_back(0);
0167 }
0168 }
0169 }
0170
0171 int smallest_time = 999999, tmp_coarse_wirepos_1 = -1, tmp_coarse_wirepos_3 = -1;
0172
0173 for (int isl = 0; isl < 3; isl++) {
0174 if (isl != sl)
0175 continue;
0176 int myisl = isl < 2 ? 0 : 1;
0177 for (size_t i = 0; i < NUM_LAYERS; i++) {
0178 if (fit_common_in.hits_valid[NUM_LAYERS * myisl + i] == 0)
0179 continue;
0180 else if (fit_common_in.hits[NUM_LAYERS * myisl + i].ti < smallest_time)
0181 smallest_time = fit_common_in.hits[NUM_LAYERS * myisl + i].ti;
0182 }
0183 if (fit_common_in.hits_valid[NUM_LAYERS * myisl + 0] == 1)
0184 tmp_coarse_wirepos_1 = fit_common_in.hits[NUM_LAYERS * myisl + 0].wp;
0185 else
0186 tmp_coarse_wirepos_1 = fit_common_in.hits[NUM_LAYERS * myisl + 1].wp;
0187 if (fit_common_in.hits_valid[NUM_LAYERS * myisl + 3] == 1)
0188 tmp_coarse_wirepos_3 = fit_common_in.hits[NUM_LAYERS * myisl + 3].wp;
0189 else
0190 tmp_coarse_wirepos_3 = fit_common_in.hits[NUM_LAYERS * myisl + 2].wp;
0191
0192 tmp_coarse_wirepos_1 = tmp_coarse_wirepos_1 >> WIREPOS_NORM_LSB_IGNORED;
0193 tmp_coarse_wirepos_3 = tmp_coarse_wirepos_3 >> WIREPOS_NORM_LSB_IGNORED;
0194 }
0195 fit_common_in.coarse_bctr = smallest_time >> (WIDTH_FULL_TIME - WIDTH_COARSED_TIME);
0196 fit_common_in.coarse_wirepos = (tmp_coarse_wirepos_1 + tmp_coarse_wirepos_3) >> 1;
0197
0198 for (auto &lat_comb : lat_combs) {
0199 if (lat_comb[0] == 0 && lat_comb[1] == 0 && lat_comb[2] == 0 && lat_comb[3] == 0)
0200 continue;
0201 fit_common_in.lateralities.clear();
0202
0203 auto rom_addr = get_rom_addr(inMPath, lat_comb);
0204 coeffs_t coeffs;
0205 if (sl == 0) {
0206 coeffs =
0207 RomDataConvert(lut_sl1[rom_addr], COEFF_WIDTH_SL_T0, COEFF_WIDTH_SL_POSITION, COEFF_WIDTH_SL_SLOPE, 0, 3);
0208 } else if (sl == 1) {
0209 coeffs =
0210 RomDataConvert(lut_sl2[rom_addr], COEFF_WIDTH_SL_T0, COEFF_WIDTH_SL2_POSITION, COEFF_WIDTH_SL_SLOPE, 0, 3);
0211 } else {
0212 coeffs =
0213 RomDataConvert(lut_sl3[rom_addr], COEFF_WIDTH_SL_T0, COEFF_WIDTH_SL_POSITION, COEFF_WIDTH_SL_SLOPE, 4, 7);
0214 }
0215
0216 int minISL = 1;
0217 int maxISL = 3;
0218 if (sl < 1) {
0219 minISL = 0;
0220 maxISL = 2;
0221 }
0222
0223 for (int isl = minISL; isl < maxISL; isl++) {
0224 for (size_t i = 0; i < NUM_LAYERS; i++) {
0225 if (isl == sl) {
0226 fit_common_in.lateralities.push_back(lat_comb[i]);
0227 } else
0228 fit_common_in.lateralities.push_back(-1);
0229 }
0230 }
0231 fit_common_in.coeffs = coeffs;
0232
0233 auto fit_common_out = fit(fit_common_in,
0234 XI_SL_WIDTH,
0235 COEFF_WIDTH_SL_T0,
0236 sl == 1 ? COEFF_WIDTH_SL2_POSITION : COEFF_WIDTH_SL_POSITION,
0237 COEFF_WIDTH_SL_SLOPE,
0238 PRECISSION_SL_T0,
0239 PRECISSION_SL_POSITION,
0240 PRECISSION_SL_SLOPE,
0241 PROD_RESIZE_SL_T0,
0242 sl == 1 ? PROD_RESIZE_SL2_POSITION : PROD_RESIZE_SL_POSITION,
0243 PROD_RESIZE_SL_SLOPE,
0244 max_drift_tdc,
0245 sl + 1);
0246
0247 if (fit_common_out.valid_fit == 1) {
0248 float t0_f = ((float)fit_common_out.t0) * (float)LHC_CLK_FREQ / (float)TIME_TO_TDC_COUNTS;
0249
0250 float slope_f = -fit_common_out.slope * ((float)CELL_SEMILENGTH / max_drift_tdc) * (1) / (CELL_SEMIHEIGHT * 16.);
0251 if (sl != 1 && std::abs(slope_f) > tanPhiTh_)
0252 continue;
0253
0254 DTWireId wireId(MuonPathSLId, 2, 1);
0255 float pos_ch_f = (float)(fit_common_out.position) * ((float)CELL_SEMILENGTH / (float)max_drift_tdc) / 10;
0256 pos_ch_f += (SL1_CELLS_OFFSET * CELL_LENGTH) / 10.;
0257 if (sl != 1)
0258 pos_ch_f += shiftinfo_[wireIdSL1.rawId()];
0259 else if (sl == 1)
0260 pos_ch_f += shiftthetainfo_[wireIdSL2.rawId()];
0261
0262 float pos_sl_f = pos_ch_f - (sl - 1) * slope_f * VERT_PHI1_PHI3 / 2;
0263 float chi2_f = fit_common_out.chi2 * std::pow(((float)CELL_SEMILENGTH / (float)max_drift_tdc), 2) / 100;
0264
0265
0266 int pos = (int)(10 * (pos_sl_f - shiftinfo_[wireId.rawId()]) * INCREASED_RES_POS_POW);
0267
0268 LogDebug("MuonPathSLFitter")
0269 << "========================= SUPERLAYER PRIMITIVE =================================";
0270 LogDebug("MuonPathSLFitter") << "WHEEL = " << ChId.wheel();
0271 LogDebug("MuonPathSLFitter") << "SECTOR = " << ChId.sector();
0272 LogDebug("MuonPathSLFitter") << "STATION = " << ChId.station();
0273 LogDebug("MuonPathSLFitter") << "SUPERLAYER = " << sl;
0274 LogDebug("MuonPathSLFitter") << "QUALITY = " << quality;
0275 LogDebug("MuonPathSLFitter") << "POSITION = " << (double)fit_common_out.position;
0276 LogDebug("MuonPathSLFitter") << "SLOPE = " << (double)fit_common_out.slope;
0277
0278 auto global_coords = globalcoordsobtainer_->get_global_coordinates(
0279 ChId.rawId(), sl + 1, fit_common_out.position, fit_common_out.slope);
0280 float phi = global_coords[0];
0281 float phiB = global_coords[1];
0282
0283
0284 double z = 0;
0285 if (ChId.station() == 3 or ChId.station() == 4) {
0286 z = Z_SHIFT_MB4;
0287 }
0288 GlobalPoint jm_x_cmssw_global = dtGeo_->chamber(ChId)->toGlobal(LocalPoint(pos_sl_f, 0., z));
0289 int thisec = ChId.sector();
0290 if (thisec == 13)
0291 thisec = 4;
0292 if (thisec == 14)
0293 thisec = 10;
0294 float phi_cmssw = jm_x_cmssw_global.phi() - PHI_CONV * (thisec - 1);
0295 float psi = atan(slope_f);
0296 float phiB_cmssw = hasPosRF(ChId.wheel(), ChId.sector()) ? psi - phi_cmssw : -psi - phi_cmssw;
0297 if (sl == 0)
0298 metaPrimitives.emplace_back(metaPrimitive({MuonPathSLId.rawId(),
0299 t0_f,
0300 (double)(fit_common_out.position),
0301 (double)fit_common_out.slope,
0302 phi,
0303 phiB,
0304 phi_cmssw,
0305 phiB_cmssw,
0306 chi2_f,
0307 quality,
0308 inMPath->primitive(0)->channelId(),
0309 inMPath->primitive(0)->tdcTimeStamp(),
0310 lat_comb[0],
0311 inMPath->primitive(1)->channelId(),
0312 inMPath->primitive(1)->tdcTimeStamp(),
0313 lat_comb[1],
0314 inMPath->primitive(2)->channelId(),
0315 inMPath->primitive(2)->tdcTimeStamp(),
0316 lat_comb[2],
0317 inMPath->primitive(3)->channelId(),
0318 inMPath->primitive(3)->tdcTimeStamp(),
0319 lat_comb[3],
0320 -1,
0321 -1,
0322 -1,
0323 -1,
0324 -1,
0325 -1,
0326 -1,
0327 -1,
0328 -1,
0329 -1,
0330 -1,
0331 -1,
0332 -1}));
0333 else if (sl == 2)
0334 metaPrimitives.emplace_back(metaPrimitive({MuonPathSLId.rawId(),
0335 t0_f,
0336 (double)(fit_common_out.position),
0337 (double)fit_common_out.slope,
0338 phi,
0339 phiB,
0340 phi_cmssw,
0341 phiB_cmssw,
0342 chi2_f,
0343 quality,
0344 -1,
0345 -1,
0346 -1,
0347 -1,
0348 -1,
0349 -1,
0350 -1,
0351 -1,
0352 -1,
0353 -1,
0354 -1,
0355 -1,
0356 inMPath->primitive(0)->channelId(),
0357 inMPath->primitive(0)->tdcTimeStamp(),
0358 lat_comb[0],
0359 inMPath->primitive(1)->channelId(),
0360 inMPath->primitive(1)->tdcTimeStamp(),
0361 lat_comb[1],
0362 inMPath->primitive(2)->channelId(),
0363 inMPath->primitive(2)->tdcTimeStamp(),
0364 lat_comb[2],
0365 inMPath->primitive(3)->channelId(),
0366 inMPath->primitive(3)->tdcTimeStamp(),
0367 lat_comb[3],
0368 -1}));
0369 else if (sl == 1) {
0370
0371 DTLayerId SL2_layer2Id(MuonPathSLId, 2);
0372 double z_shift = shiftthetainfo_[SL2_layer2Id.rawId()];
0373 double pos_cm =
0374 pos / 10 / INCREASED_RES_POS_POW;
0375 double jm_y = hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? z_shift - pos_cm : z_shift + pos_cm;
0376
0377 phi = jm_y;
0378
0379
0380 double k_fromfw = hasPosRF(MuonPathSLId.wheel(), MuonPathSLId.sector()) ? slope_f : -slope_f;
0381 phiB = k_fromfw;
0382
0383
0384 LocalPoint wire1_in_layer(dtGeo_->layer(SL2_layer2Id)->specificTopology().wirePosition(1), 0, -0.65);
0385 GlobalPoint wire1_in_global = dtGeo_->layer(SL2_layer2Id)->toGlobal(wire1_in_layer);
0386 LocalPoint wire1_in_sl = dtGeo_->superLayer(MuonPathSLId)->toLocal(wire1_in_global);
0387 double x_shift = wire1_in_sl.x();
0388 jm_y = (dtGeo_->superLayer(MuonPathSLId)
0389 ->toGlobal(LocalPoint(double(pos) / (10 * pow(2, INCREASED_RES_POS)) + x_shift, 0., 0)))
0390 .z();
0391 phi_cmssw = jm_y;
0392
0393 double x_cmssw = (dtGeo_->superLayer(MuonPathSLId)
0394 ->toGlobal(LocalPoint(double(pos) / (10 * pow(2, INCREASED_RES_POS)) + x_shift, 0., 0)))
0395 .x();
0396 double y_cmssw = (dtGeo_->superLayer(MuonPathSLId)
0397 ->toGlobal(LocalPoint(double(pos) / (10 * pow(2, INCREASED_RES_POS)) + x_shift, 0., 0)))
0398 .y();
0399 double r_cmssw = sqrt(x_cmssw * x_cmssw + y_cmssw * y_cmssw);
0400 double k_cmssw = jm_y / r_cmssw;
0401 phiB_cmssw = k_cmssw;
0402
0403 metaPrimitives.emplace_back(metaPrimitive({MuonPathSLId.rawId(),
0404 t0_f,
0405 (double)(fit_common_out.position),
0406 (double)fit_common_out.slope,
0407 phi,
0408 phiB,
0409 phi_cmssw,
0410 phiB_cmssw,
0411 chi2_f,
0412 quality,
0413 inMPath->primitive(0)->channelId(),
0414 inMPath->primitive(0)->tdcTimeStamp(),
0415 lat_comb[0],
0416 inMPath->primitive(1)->channelId(),
0417 inMPath->primitive(1)->tdcTimeStamp(),
0418 lat_comb[1],
0419 inMPath->primitive(2)->channelId(),
0420 inMPath->primitive(2)->tdcTimeStamp(),
0421 lat_comb[2],
0422 inMPath->primitive(3)->channelId(),
0423 inMPath->primitive(3)->tdcTimeStamp(),
0424 lat_comb[3],
0425 -1,
0426 -1,
0427 -1,
0428 -1,
0429 -1,
0430 -1,
0431 -1,
0432 -1,
0433 -1,
0434 -1,
0435 -1,
0436 -1,
0437 -1}));
0438 }
0439 }
0440 }
0441 return;
0442 }
0443
0444 void MuonPathSLFitter::fillLuts() {
0445 std::ifstream ifinsl1(sl1_filename_.fullPath());
0446 std::string line;
0447 while (ifinsl1.good()) {
0448 ifinsl1 >> line;
0449
0450 std::vector<int> myNumbers;
0451 for (size_t i = 0; i < line.size(); i++) {
0452
0453 myNumbers.push_back(line[i] - '0');
0454 }
0455 std::reverse(myNumbers.begin(), myNumbers.end());
0456 lut_sl1.push_back(myNumbers);
0457 }
0458
0459 std::ifstream ifinsl2(sl2_filename_.fullPath());
0460 while (ifinsl2.good()) {
0461 ifinsl2 >> line;
0462
0463 std::vector<int> myNumbers;
0464 for (size_t i = 0; i < line.size(); i++) {
0465
0466 myNumbers.push_back(line[i] - '0');
0467 }
0468 std::reverse(myNumbers.begin(), myNumbers.end());
0469 lut_sl2.push_back(myNumbers);
0470 }
0471
0472 std::ifstream ifinsl3(sl3_filename_.fullPath());
0473 while (ifinsl3.good()) {
0474 ifinsl3 >> line;
0475
0476 std::vector<int> myNumbers;
0477 for (size_t i = 0; i < line.size(); i++) {
0478
0479 myNumbers.push_back(line[i] - '0');
0480 }
0481 std::reverse(myNumbers.begin(), myNumbers.end());
0482 lut_sl3.push_back(myNumbers);
0483 }
0484
0485 return;
0486 }
0487
0488 int MuonPathSLFitter::get_rom_addr(MuonPathPtr &inMPath, latcomb lats) {
0489 std::vector<int> rom_addr;
0490 auto missing_layer = inMPath->missingLayer();
0491 if (missing_layer == -1) {
0492 rom_addr.push_back(1);
0493 rom_addr.push_back(0);
0494 } else {
0495 if (missing_layer == 0) {
0496 rom_addr.push_back(0);
0497 rom_addr.push_back(0);
0498 } else if (missing_layer == 1) {
0499 rom_addr.push_back(0);
0500 rom_addr.push_back(1);
0501 } else if (missing_layer == 2) {
0502 rom_addr.push_back(1);
0503 rom_addr.push_back(0);
0504 } else {
0505 rom_addr.push_back(1);
0506 rom_addr.push_back(1);
0507 }
0508 }
0509 for (size_t ilat = 0; ilat < lats.size(); ilat++) {
0510 if ((int)ilat == missing_layer)
0511 continue;
0512 auto lat = lats[ilat];
0513 if (lat == -1)
0514 lat = 0;
0515 rom_addr.push_back(lat);
0516 }
0517 std::reverse(rom_addr.begin(), rom_addr.end());
0518 return vhdl_unsigned_to_int(rom_addr);
0519 }