00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "L1Trigger/DTUtilities/interface/DTTrigGeom.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <iostream>
00028 #include <iomanip>
00029 #include <fstream>
00030 #include <sstream>
00031 #include <cstring>
00032
00033
00034
00035
00036 #include "Geometry/DTGeometry/interface/DTTopology.h"
00037 #include "Geometry/DTGeometry/interface/DTLayer.h"
00038 #include "Geometry/DTGeometry/interface/DTSuperLayer.h"
00039 #include "Geometry/DTGeometry/interface/DTChamber.h"
00040 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00041 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00042 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
00043 #include "DataFormats/GeometryVector/interface/LocalVector.h"
00044
00045 using namespace std;
00046
00047
00048
00049
00050
00051 DTTrigGeom::DTTrigGeom(DTChamber* stat, bool debug) : _stat(stat) , _debug(debug) {
00052
00053 getGeom();
00054
00055 }
00056
00057
00058
00059
00060
00061
00062 DTTrigGeom::~DTTrigGeom() {}
00063
00064
00065
00066
00067
00068
00069 float
00070 DTTrigGeom::phiSLOffset(){
00071
00072 float x1 = tubePosInCh(1,1,1).x();
00073 float x3 = tubePosInCh(3,1,1).x();
00074 float offset = x1-x3;
00075
00076
00077
00078 return offset;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 int
00143 DTTrigGeom::mapTubeInFEch(int nsl, int nlay, int ntube) const {
00144 int nch = 0;
00145 if(station()==4 && nsl==2){
00146 std::cout << "No theta superlayer in station 4!" << std::endl;
00147 }
00148 else{
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 nch =ntube;
00160
00161
00162
00163 }
00164 return nch;
00165 }
00166
00167 LocalPoint
00168 DTTrigGeom::tubePosInCh(int nsl, int nlay, int ntube) const {
00169 if ( nlay==4 && ntube==1) {
00170 std::cout << "ATTENTION: no wire nuber 1 for 4th layer!!!" << std::endl;
00171 LocalPoint dummyLP(0,0,0);
00172 return dummyLP;
00173 }
00174 const DTSuperLayer* sl = _stat->superLayer(DTSuperLayerId(statId(),nsl));
00175 const DTLayer* lay = sl->layer(DTLayerId(statId(),nsl,nlay));
00176
00177 float localX = lay->specificTopology().wirePosition(ntube);
00178 LocalPoint posInLayer(localX,0,0);
00179 LocalPoint posInChamber = _stat->surface().toLocal(lay->toGlobal(posInLayer));
00180
00181
00182
00183
00184
00185
00186 return posInChamber;
00187 }
00188
00189 int
00190 DTTrigGeom::posFE(int sl) const {
00191 if( station()!=4 || sl!=2 ) {
00192
00193 return 1;
00194 }
00195 else{
00196 std::cout << "No theta superlayer in station 4!" << std::endl;
00197 return 0;
00198 }
00199 }
00200
00201 void
00202 DTTrigGeom::setGeom(const DTChamber* stat) {
00203
00204 _stat=stat;
00205 getGeom();
00206
00207 }
00208
00209 void
00210 DTTrigGeom::getGeom() {
00211
00212
00213
00214 _PITCH = 4.2;
00215
00216 _H = 1.3;
00217
00218 _PHICH = _stat->surface().toGlobal(LocalVector(0,0,-1)).phi();
00219
00220
00221 DTSuperLayer* sl[3];
00222 DTLayer* l1[3];
00223 int i = 0;
00224 for(i=0; i<3; i++) {
00225 if(station()==4&&i==1) {
00226 _ZSL[i] = -999;
00227 _NCELL[i] = 0;
00228 } else {
00229 sl[i] = (DTSuperLayer*) _stat->superLayer(DTSuperLayerId(statId(),i+1));
00230 l1[i] = (DTLayer*) sl[i]->layer(DTLayerId(statId(),i+1,1));
00231 _ZSL[i] = _stat->surface().toLocal(sl[i]->position()).z();
00232
00233 const DTTopology& tp=l1[i]->specificTopology();
00234 float posX=tp.wirePosition(tp.firstChannel());
00235 LocalPoint posInLayer(posX,0,0);
00236 _NCELL[i] = l1[i]->specificTopology().channels();
00237 }
00238 }
00239
00240
00241 if(_debug){
00242 std::cout << setiosflags(std::ios::showpoint | std::ios::fixed) << std::setw(4) <<
00243 std::setprecision(1);
00244 std::cout << "Identification: wheel=" << wheel();
00245 std::cout << ", station=" << station();
00246 std::cout << ", sector=" << sector() << std::endl;
00247 GlobalPoint pp = _stat->toGlobal(LocalPoint(0,0,0));
00248 std::cout << "Position: Mag=" << pp.mag() << "cm, Phi=" << pp.phi()*180/3.14159;
00249 std::cout << " deg, Z=" << pp.z() << " cm" << std::endl;
00250 std::cout << "Rotation: ANGLE=" << phiCh()*180/3.14159 << std::endl;
00251
00252 std::cout << "Z of superlayers: phi=" << ZSL(1) << ", ";
00253 std::cout << ZSL(3) << " theta=" << ZSL(2);
00254 std::cout << " (DeltaY = " << distSL() << ")" << std::endl;
00255 std::cout << " ncell: sl 1 " << nCell(1) << " sl 2 " << nCell(2) <<
00256 " sl 3 " << nCell(3) << std::endl;
00257
00258 }
00259
00260
00261 }
00262
00263 float
00264 DTTrigGeom::ZSL(int sl) const {
00265 if(sl<1||sl>3){
00266 std::cout << "DTTrigGeom::ZSL: wrong SL number: " << sl;
00267 std::cout << -999 << " returned" << std::endl;
00268 return -999;
00269 }
00270 return _ZSL[sl-1];
00271 }
00272
00273
00274 void
00275 DTTrigGeom::dumpGeom() const {
00276 std::cout << "Identification: wheel=" << wheel();
00277 std::cout << ", station=" << station();
00278 std::cout << ", sector=" << sector() << std::endl;
00279 GlobalPoint pp = _stat->toGlobal(LocalPoint(0,0,0));
00280 std::cout << "Position: Mag=" << pp.mag() << "cm, Phi=" << pp.phi()*180/3.14159;
00281 std::cout << " deg, Z=" << pp.z() << " cm" << std::endl;
00282 std::cout << "Rotation: ANGLE=" << phiCh()*180/3.14159 << std::endl;
00283 std::cout << "Z of superlayers: phi=" << ZSL(1) << ", ";
00284 std::cout << ZSL(3) << " theta=" << ZSL(2) << std::endl;
00285 std::cout << "Number of cells: SL1=" << nCell(1) << " SL2=" << nCell(2) <<
00286 " SL3=" << nCell(3) << std::endl;
00287 std::cout << "First wire positions:" << std::endl;
00288 int ii=0;
00289 int jj=0;
00290 for( ii = 1; ii<=3; ii++ ) {
00291 if(station()!=4||ii!=2){
00292 for ( jj =1; jj<=4; jj++ ) {
00293 std::cout << " SL=" << ii << ", lay=" << jj << ", wire 1 position=";
00294 if ( jj ==4)
00295 std::cout << tubePosInCh( ii, jj, 2) << std::endl;
00296 else
00297 std::cout << tubePosInCh( ii, jj, 1) << std::endl;
00298 }
00299 }
00300 }
00301
00302 GlobalPoint gp1 = CMSPosition(DTBtiId(statId(),1,1));
00303
00304
00305 std::cout << "First BTI position:";
00306 std::cout << " SL1:" << localPosition(DTBtiId(statId(),1,1)) << std::endl;
00307 std::cout << " Position: R=" << gp1.perp() << "cm, Phi=" << gp1.phi()*180/3.14159 << " deg, Z=" << gp1.z() << " cm" << std::endl;
00308
00309 if(station()!=4)
00310 {
00311 GlobalPoint gp2 = CMSPosition(DTBtiId(statId(),2,1));
00312 std::cout << " SL2:" << localPosition(DTBtiId(statId(),2,1))<< std::endl;
00313 std::cout << " Position: R=" << gp2.perp() << "cm, Phi=" << gp2.phi()*180/3.14159 << " deg, Z=" << gp2.z() << " cm" << std::endl;
00314 }
00315
00316 GlobalPoint gp3 = CMSPosition(DTBtiId(statId(),3,1));
00317 std::cout << " SL3:" << localPosition(DTBtiId(statId(),3,1)) << std::endl;
00318 std::cout << " Position: R=" << gp3.perp() << "cm, Phi=" << gp3.phi()*180/3.14159 << " deg, Z=" << gp3.z() << " cm" << std::endl;
00319
00320 std::cout << "First TRACO position:";
00321 std::cout << localPosition(DTTracoId(statId(),1)) << std::endl;
00322 std::cout << "******************************************************" << std::endl;
00323 }
00324
00325 void
00326 DTTrigGeom::dumpLUT(short int btic) {
00327
00328
00329 int wh = wheel();
00330 int st = station();
00331 int se = sector();
00332
00333
00334 string name = "Lut_from_CMSSW_geom";
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 name += ".txt";
00351
00352 ofstream fout;
00353 fout.open(name.c_str(),ofstream::app);
00354
00355
00356
00357
00358
00359 fout << wh;
00360 fout << "\t" << st;
00361 fout << "\t" << se;
00362
00363
00364 float xBTI1_3 = localPosition( DTBtiId(DTSuperLayerId(wheel(),station(),sector(),3),1) ).x();
00365 float xBTI1_1 = localPosition( DTBtiId(DTSuperLayerId(wheel(),station(),sector(),1),1) ).x();
00366 float SL_shift = xBTI1_3 - xBTI1_1;
00367
00368
00369
00370 LocalPoint traco1 = localPosition(DTTracoId(statId(),1));
00371 LocalPoint traco2 = localPosition(DTTracoId(statId(),2));
00372 GlobalPoint traco_1 = toGlobal(traco1);
00373 GlobalPoint traco_2 = toGlobal(traco2);
00374
00375
00376 float d;
00377 float xcn;
00378 int xcn_sign;
00379 GlobalPoint pp = _stat->toGlobal(LocalPoint(0,0,ZcenterSL()));
00380
00381
00382 if(sector()==1 || sector() ==7){
00383 d = fabs(traco_1.x());
00384 xcn = fabs(traco_1.y());
00385
00386 if (SL_shift > 0)
00387 xcn = xcn+SL_shift;
00388 xcn_sign = static_cast<int>(pp.y()/fabs(pp.y()))*static_cast<int>(traco_1.y()/fabs(traco_1.y()));
00389 if(station() == 2 || (station() == 4 && sector() == 1))
00390 xcn_sign = - xcn_sign;
00391 xcn = xcn*xcn_sign;
00392 }
00393 else {
00394 float m1 = (traco_2.y()-traco_1.y())/(traco_2.x()-traco_1.x());
00395 float q1 = traco_1.y()-m1*traco_1.x();
00396 float m = tan(phiCh());
00397 float xn = q1/(m-m1);
00398 float yn = m*xn;
00399
00400 d = sqrt(xn*xn+yn*yn);
00401 xcn = sqrt( (xn-traco_1.x())*(xn-traco_1.x()) + (yn-traco_1.y())*(yn-traco_1.y()) );
00402
00403 if (SL_shift > 0)
00404 xcn = xcn+SL_shift;
00405
00406 float diff = (pp.x()-traco_1.x())*traco_1.y();
00407 xcn_sign = static_cast<int>(diff/fabs(diff));
00408 xcn = xcn*xcn_sign;
00409 }
00410
00411
00412
00413
00414
00415 fout << "\tA8";
00416
00417
00418 short int Low_byte = (btic & 0x00FF);
00419 short int High_byte =( btic>>8 & 0x00FF);
00420 fout << setw(2) << setfill('0') << hex << High_byte << setw(2) << setfill('0') << Low_byte;
00421
00422
00423 short int DSPmantissa = 0;
00424 short int DSPexp = 0;
00425
00426
00427 IEEE32toDSP(d, DSPmantissa, DSPexp);
00428 Low_byte = (DSPmantissa & 0x00FF);
00429 High_byte =( DSPmantissa>>8 & 0x00FF);
00430 fout << setw(2) << setfill('0') << hex << High_byte << setw(2) << setfill('0') << Low_byte;
00431 Low_byte = (DSPexp & 0x00FF);
00432 High_byte =( DSPexp>>8 & 0x00FF);
00433 fout << setw(2) << setfill('0') << High_byte << setw(2) << setfill('0') << Low_byte;
00434
00435
00436 DSPmantissa = 0;
00437 DSPexp = 0;
00438 IEEE32toDSP(xcn, DSPmantissa, DSPexp);
00439 Low_byte = (DSPmantissa & 0x00FF);
00440 High_byte =( DSPmantissa>>8 & 0x00FF);
00441 fout << setw(2) << setfill('0') << hex << High_byte << setw(2) << setfill('0') << Low_byte;
00442 Low_byte = (DSPexp & 0x00FF);
00443 High_byte =( DSPexp>>8 & 0x00FF);
00444 fout << setw(2) << setfill('0') << High_byte << setw(2) << setfill('0') << Low_byte;
00445
00446
00447 Low_byte = (xcn_sign & 0x00FF);
00448 High_byte =( xcn_sign>>8 & 0x00FF);
00449 fout << setw(2) << setfill('0') << hex << High_byte << setw(2) << setfill('0') << Low_byte << dec << "\n";
00450
00451 fout.close();
00452
00453 return;
00454
00455 }
00456
00457 void
00458 DTTrigGeom::IEEE32toDSP(float f, short int & DSPmantissa, short int & DSPexp)
00459 {
00460 long int *pl=0, lm;
00461 bool sign=false;
00462
00463 DSPmantissa = 0;
00464 DSPexp = 0;
00465
00466 if( f!=0.0 )
00467 {
00468 memcpy(pl,&f,sizeof(float));
00469 if((*pl & 0x80000000)!=0)
00470 sign=true;
00471 lm = ( 0x800000 | (*pl & 0x7FFFFF));
00472 lm >>= 9;
00473 lm &= 0x7FFF;
00474 DSPexp = ((*pl>>23)&0xFF)-126;
00475 DSPmantissa = (short)lm;
00476 if(sign)
00477 DSPmantissa = - DSPmantissa;
00478
00479 }
00480 return;
00481 }
00482
00483
00484 LocalPoint
00485 DTTrigGeom::localPosition(const DTBtiId id) const {
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 int nsl = id.superlayer();
00527 const DTSuperLayer* sl = _stat->superLayer(DTSuperLayerId(statId(),nsl));
00528 const DTLayer* lay = sl->layer(DTLayerId(statId(),nsl,1));
00529 int tube = id.bti();
00530 float localX = lay->specificTopology().wirePosition(tube);
00531 float xt = -cellPitch()/2.;
00532 float zt = -cellH() * 3./2.;
00533
00534 LocalPoint posInLayer1(localX+xt,0,zt);
00535 LocalPoint posInChamber = _stat->surface().toLocal(lay->toGlobal(posInLayer1));
00536
00537
00538
00539
00540
00541
00542 return posInChamber;
00543 }
00544
00545 LocalPoint
00546 DTTrigGeom::localPosition(const DTTracoId id) const {
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 float x = localPosition( DTBtiId(DTSuperLayerId(wheel(),station(),sector(),3),1) ).x();
00558
00559
00560
00561
00562 x += (id.traco()-2)*DTConfig::NBTITC * cellPitch();
00563
00564 float y = 0;
00565 float z = ZcenterSL();
00566
00567 return LocalPoint(x,y,z);
00568 }