File indexing completed on 2024-04-06 12:19:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "L1Trigger/DTUtilities/interface/DTTrigGeom.h"
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include <cstring>
0029 #include <fstream>
0030 #include <iomanip>
0031 #include <iostream>
0032 #include <sstream>
0033
0034
0035
0036
0037 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0038 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
0039 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
0040 #include "DataFormats/GeometryVector/interface/LocalVector.h"
0041 #include "Geometry/DTGeometry/interface/DTChamber.h"
0042 #include "Geometry/DTGeometry/interface/DTLayer.h"
0043 #include "Geometry/DTGeometry/interface/DTSuperLayer.h"
0044 #include "Geometry/DTGeometry/interface/DTTopology.h"
0045
0046 using namespace std;
0047
0048
0049
0050
0051
0052 DTTrigGeom::DTTrigGeom(const DTChamber *stat, bool debug) : _stat(stat), _debug(debug) { getGeom(); }
0053
0054
0055
0056
0057
0058 DTTrigGeom::~DTTrigGeom() {}
0059
0060
0061
0062
0063
0064 float DTTrigGeom::phiSLOffset() {
0065
0066 float x1 = tubePosInCh(1, 1, 1).x();
0067 float x3 = tubePosInCh(3, 1, 1).x();
0068 float offset = x1 - x3;
0069
0070
0071
0072 return offset;
0073 }
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144 int DTTrigGeom::mapTubeInFEch(int nsl, int nlay, int ntube) const {
0145 int nch = 0;
0146 if (station() == 4 && nsl == 2) {
0147 std::cout << "No theta superlayer in station 4!" << std::endl;
0148 } else {
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 nch = ntube;
0163
0164
0165
0166 }
0167 return nch;
0168 }
0169
0170 LocalPoint DTTrigGeom::tubePosInCh(int nsl, int nlay, int ntube) const {
0171 if (nlay == 4 && ntube == 1) {
0172 std::cout << "ATTENTION: no wire nuber 1 for 4th layer!!!" << std::endl;
0173 LocalPoint dummyLP(0, 0, 0);
0174 return dummyLP;
0175 }
0176 const DTSuperLayer *sl = _stat->superLayer(DTSuperLayerId(statId(), nsl));
0177 const DTLayer *lay = sl->layer(DTLayerId(statId(), nsl, nlay));
0178
0179 float localX = lay->specificTopology().wirePosition(ntube);
0180 LocalPoint posInLayer(localX, 0, 0);
0181 LocalPoint posInChamber = _stat->surface().toLocal(lay->toGlobal(posInLayer));
0182
0183
0184
0185
0186
0187
0188
0189 return posInChamber;
0190 }
0191
0192 int DTTrigGeom::posFE(int sl) const {
0193 if (station() != 4 || sl != 2) {
0194
0195
0196 return 1 ;
0197 } else {
0198 std::cout << "No theta superlayer in station 4!" << std::endl;
0199 return 0;
0200 }
0201 }
0202
0203 void DTTrigGeom::setGeom(const DTChamber *stat) {
0204 _stat = stat;
0205 getGeom();
0206 }
0207
0208 void DTTrigGeom::getGeom() {
0209
0210
0211 _PITCH = 4.2;
0212
0213 _H = 1.3;
0214
0215 _PHICH = _stat->surface().toGlobal(LocalVector(0, 0, -1)).phi();
0216
0217
0218 DTSuperLayer const *sl[3];
0219 DTLayer const *l1[3];
0220 int i = 0;
0221 for (i = 0; i < 3; i++) {
0222 if (station() == 4 && i == 1) {
0223 _ZSL[i] = -999;
0224 _NCELL[i] = 0;
0225 } else {
0226 sl[i] = _stat->superLayer(DTSuperLayerId(statId(), i + 1));
0227 l1[i] = sl[i]->layer(DTLayerId(statId(), i + 1, 1));
0228 _ZSL[i] = _stat->surface().toLocal(sl[i]->position()).z();
0229
0230 const DTTopology &tp = l1[i]->specificTopology();
0231 float posX = tp.wirePosition(tp.firstChannel());
0232 LocalPoint posInLayer(posX, 0, 0);
0233 _NCELL[i] = l1[i]->specificTopology().channels();
0234 }
0235 }
0236
0237
0238 if (_debug) {
0239 std::cout << setiosflags(std::ios::showpoint | std::ios::fixed) << std::setw(4) << std::setprecision(1);
0240 std::cout << "Identification: wheel=" << wheel();
0241 std::cout << ", station=" << station();
0242 std::cout << ", sector=" << sector() << std::endl;
0243 GlobalPoint pp = _stat->toGlobal(LocalPoint(0, 0, 0));
0244 std::cout << "Position: Mag=" << pp.mag() << "cm, Phi=" << pp.phi() * 180 / 3.14159;
0245 std::cout << " deg, Z=" << pp.z() << " cm" << std::endl;
0246 std::cout << "Rotation: ANGLE=" << phiCh() * 180 / 3.14159 << std::endl;
0247
0248 std::cout << "Z of superlayers: phi=" << ZSL(1) << ", ";
0249 std::cout << ZSL(3) << " theta=" << ZSL(2);
0250 std::cout << " (DeltaY = " << distSL() << ")" << std::endl;
0251 std::cout << " ncell: sl 1 " << nCell(1) << " sl 2 " << nCell(2) << " sl 3 " << nCell(3) << std::endl;
0252
0253 }
0254
0255 }
0256
0257 float DTTrigGeom::ZSL(int sl) const {
0258 if (sl < 1 || sl > 3) {
0259 std::cout << "DTTrigGeom::ZSL: wrong SL number: " << sl;
0260 std::cout << -999 << " returned" << std::endl;
0261 return -999;
0262 }
0263 return _ZSL[sl - 1];
0264 }
0265
0266 void DTTrigGeom::dumpGeom() const {
0267 std::cout << "Identification: wheel=" << wheel();
0268 std::cout << ", station=" << station();
0269 std::cout << ", sector=" << sector() << std::endl;
0270 GlobalPoint pp = _stat->toGlobal(LocalPoint(0, 0, 0));
0271 std::cout << "Position: Mag=" << pp.mag() << "cm, Phi=" << pp.phi() * 180 / 3.14159;
0272 std::cout << " deg, Z=" << pp.z() << " cm" << std::endl;
0273 std::cout << "Rotation: ANGLE=" << phiCh() * 180 / 3.14159 << std::endl;
0274 std::cout << "Z of superlayers: phi=" << ZSL(1) << ", ";
0275 std::cout << ZSL(3) << " theta=" << ZSL(2) << std::endl;
0276 std::cout << "Number of cells: SL1=" << nCell(1) << " SL2=" << nCell(2) << " SL3=" << nCell(3) << std::endl;
0277 std::cout << "First wire positions:" << std::endl;
0278 int ii = 0;
0279 int jj = 0;
0280 for (ii = 1; ii <= 3; ii++) {
0281 if (station() != 4 || ii != 2) {
0282 for (jj = 1; jj <= 4; jj++) {
0283 std::cout << " SL=" << ii << ", lay=" << jj << ", wire 1 position=";
0284 if (jj == 4)
0285 std::cout << tubePosInCh(ii, jj, 2) << std::endl;
0286 else
0287 std::cout << tubePosInCh(ii, jj, 1) << std::endl;
0288 }
0289 }
0290 }
0291
0292 GlobalPoint gp1 = CMSPosition(DTBtiId(statId(), 1, 1));
0293
0294 std::cout << "First BTI position:";
0295 std::cout << " SL1:" << localPosition(DTBtiId(statId(), 1, 1)) << std::endl;
0296 std::cout << " Position: R=" << gp1.perp() << "cm, Phi=" << gp1.phi() * 180 / 3.14159 << " deg, Z=" << gp1.z()
0297 << " cm" << std::endl;
0298
0299 if (station() != 4) {
0300 GlobalPoint gp2 = CMSPosition(DTBtiId(statId(), 2, 1));
0301 std::cout << " SL2:" << localPosition(DTBtiId(statId(), 2, 1)) << std::endl;
0302 std::cout << " Position: R=" << gp2.perp() << "cm, Phi=" << gp2.phi() * 180 / 3.14159 << " deg, Z=" << gp2.z()
0303 << " cm" << std::endl;
0304 }
0305
0306 GlobalPoint gp3 = CMSPosition(DTBtiId(statId(), 3, 1));
0307 std::cout << " SL3:" << localPosition(DTBtiId(statId(), 3, 1)) << std::endl;
0308 std::cout << " Position: R=" << gp3.perp() << "cm, Phi=" << gp3.phi() * 180 / 3.14159 << " deg, Z=" << gp3.z()
0309 << " cm" << std::endl;
0310
0311 std::cout << "First TRACO position:";
0312 std::cout << localPosition(DTTracoId(statId(), 1)) << std::endl;
0313 std::cout << "******************************************************" << std::endl;
0314 }
0315
0316 void DTTrigGeom::dumpLUT(short int btic) {
0317
0318 int wh = wheel();
0319 int st = station();
0320 int se = sector();
0321
0322
0323 string name = "Lut_from_CMSSW_geom";
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 name += ".txt";
0340
0341 ofstream fout;
0342 fout.open(name.c_str(), ofstream::app);
0343
0344
0345
0346
0347
0348 fout << wh;
0349 fout << "\t" << st;
0350 fout << "\t" << se;
0351
0352
0353 float xBTI1_3 = localPosition(DTBtiId(DTSuperLayerId(wheel(), station(), sector(), 3), 1)).x();
0354 float xBTI1_1 = localPosition(DTBtiId(DTSuperLayerId(wheel(), station(), sector(), 1), 1)).x();
0355 float SL_shift = xBTI1_3 - xBTI1_1;
0356
0357
0358
0359 LocalPoint traco1 = localPosition(DTTracoId(statId(), 1));
0360 LocalPoint traco2 = localPosition(DTTracoId(statId(), 2));
0361 GlobalPoint traco_1 = toGlobal(traco1);
0362 GlobalPoint traco_2 = toGlobal(traco2);
0363
0364
0365
0366 float d;
0367 float xcn;
0368 int xcn_sign;
0369 GlobalPoint pp = _stat->toGlobal(LocalPoint(0, 0, ZcenterSL()));
0370
0371
0372
0373 if (sector() == 1 || sector() == 7) {
0374 d = fabs(traco_1.x());
0375 xcn = fabs(traco_1.y());
0376
0377 if (SL_shift > 0)
0378 xcn = xcn + SL_shift;
0379 xcn_sign = static_cast<int>(pp.y() / fabs(pp.y())) * static_cast<int>(traco_1.y() / fabs(traco_1.y()));
0380 if (station() == 2 || (station() == 4 && sector() == 1))
0381 xcn_sign = -xcn_sign;
0382 xcn = xcn * xcn_sign;
0383 } else {
0384 float m1 = (traco_2.y() - traco_1.y()) / (traco_2.x() - traco_1.x());
0385 float q1 = traco_1.y() - m1 * traco_1.x();
0386 float m = tan(phiCh());
0387 float xn = q1 / (m - m1);
0388 float yn = m * xn;
0389
0390 d = sqrt(xn * xn + yn * yn);
0391 xcn = sqrt((xn - traco_1.x()) * (xn - traco_1.x()) + (yn - traco_1.y()) * (yn - traco_1.y()));
0392
0393 if (SL_shift > 0)
0394 xcn = xcn + SL_shift;
0395
0396 float diff = (pp.x() - traco_1.x()) * traco_1.y();
0397 xcn_sign = static_cast<int>(diff / fabs(diff));
0398 xcn = xcn * xcn_sign;
0399 }
0400
0401
0402
0403
0404
0405
0406 fout << "\tA8";
0407
0408
0409 short int Low_byte = (btic & 0x00FF);
0410 short int High_byte = (btic >> 8 & 0x00FF);
0411 fout << setw(2) << setfill('0') << hex << High_byte << setw(2) << setfill('0') << Low_byte;
0412
0413
0414 short int DSPmantissa = 0;
0415 short int DSPexp = 0;
0416
0417
0418 IEEE32toDSP(d, DSPmantissa, DSPexp);
0419 Low_byte = (DSPmantissa & 0x00FF);
0420 High_byte = (DSPmantissa >> 8 & 0x00FF);
0421 fout << setw(2) << setfill('0') << hex << High_byte << setw(2) << setfill('0') << Low_byte;
0422 Low_byte = (DSPexp & 0x00FF);
0423 High_byte = (DSPexp >> 8 & 0x00FF);
0424 fout << setw(2) << setfill('0') << High_byte << setw(2) << setfill('0') << Low_byte;
0425
0426
0427 DSPmantissa = 0;
0428 DSPexp = 0;
0429 IEEE32toDSP(xcn, DSPmantissa, DSPexp);
0430 Low_byte = (DSPmantissa & 0x00FF);
0431 High_byte = (DSPmantissa >> 8 & 0x00FF);
0432 fout << setw(2) << setfill('0') << hex << High_byte << setw(2) << setfill('0') << Low_byte;
0433 Low_byte = (DSPexp & 0x00FF);
0434 High_byte = (DSPexp >> 8 & 0x00FF);
0435 fout << setw(2) << setfill('0') << High_byte << setw(2) << setfill('0') << Low_byte;
0436
0437
0438 Low_byte = (xcn_sign & 0x00FF);
0439 High_byte = (xcn_sign >> 8 & 0x00FF);
0440 fout << setw(2) << setfill('0') << hex << High_byte << setw(2) << setfill('0') << Low_byte << dec << "\n";
0441
0442 fout.close();
0443
0444 return;
0445 }
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482 void DTTrigGeom::IEEE32toDSP(float f, short int &DSPmantissa, short int &DSPexp) {
0483 long int lm;
0484 long int pl = 0;
0485
0486 bool sign = false;
0487
0488 DSPmantissa = 0;
0489 DSPexp = 0;
0490
0491 if (f != 0.0) {
0492 memcpy(&pl, &f, sizeof(float));
0493
0494 if ((pl & 0x80000000) != 0)
0495 sign = true;
0496 lm = (0x800000 | (pl & 0x7FFFFF));
0497 lm >>= 9;
0498 lm &= 0x7FFF;
0499 DSPexp = ((pl >> 23) & 0xFF) - 126;
0500 DSPmantissa = (short)lm;
0501 if (sign)
0502 DSPmantissa = -DSPmantissa;
0503 }
0504 return;
0505 }
0506
0507
0508 LocalPoint DTTrigGeom::localPosition(const DTBtiId id) const {
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551 int nsl = id.superlayer();
0552 const DTSuperLayer *sl = _stat->superLayer(DTSuperLayerId(statId(), nsl));
0553 const DTLayer *lay = sl->layer(DTLayerId(statId(), nsl, 1));
0554 int tube = id.bti();
0555 float localX = lay->specificTopology().wirePosition(tube);
0556 float xt = -cellPitch() / 2.;
0557 float zt = -cellH() * 3. / 2.;
0558
0559
0560 LocalPoint posInLayer1(localX + xt, 0, zt);
0561 LocalPoint posInChamber = _stat->surface().toLocal(lay->toGlobal(posInLayer1));
0562
0563
0564
0565
0566
0567
0568
0569 return posInChamber;
0570 }
0571
0572 LocalPoint DTTrigGeom::localPosition(const DTTracoId id) const {
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 float x = localPosition(DTBtiId(DTSuperLayerId(wheel(), station(), sector(), 3), 1)).x();
0584
0585
0586
0587
0588 x += (id.traco() - 2) * DTConfig::NBTITC * cellPitch();
0589
0590 float y = 0;
0591 float z = ZcenterSL();
0592
0593 return LocalPoint(x, y, z);
0594 }