Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:22:07

0001 //-------------------------------------------------
0002 //
0003 //   Class: DTTrigGeom
0004 //
0005 //   Description: Muon Barrel Trigger Geometry
0006 //
0007 //
0008 //   Author List:
0009 //   C. Grandi
0010 //   Modifications:
0011 //   S. Vanini : NEWGEO implementation
0012 //   S. Vanini 090902 : dumpLUT method implemented
0013 //   A. Gozzelino May 11th 2012: IEEE32toDSP method bug fix
0014 //--------------------------------------------------
0015 
0016 //-----------------------
0017 // This Class's Header --
0018 //-----------------------
0019 #include "L1Trigger/DTUtilities/interface/DTTrigGeom.h"
0020 
0021 //-------------
0022 // C Headers --
0023 //-------------
0024 
0025 //---------------
0026 // C++ Headers --
0027 //---------------
0028 #include <cstring>
0029 #include <fstream>
0030 #include <iomanip>
0031 #include <iostream>
0032 #include <sstream>
0033 
0034 //-------------------------------
0035 // Collaborating Class Headers --
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 // Constructors --
0050 //----------------
0051 
0052 DTTrigGeom::DTTrigGeom(const DTChamber *stat, bool debug) : _stat(stat), _debug(debug) { getGeom(); }
0053 
0054 //--------------
0055 // Destructor --
0056 //--------------
0057 
0058 DTTrigGeom::~DTTrigGeom() {}
0059 
0060 //--------------
0061 // Operations --
0062 //--------------
0063 
0064 float DTTrigGeom::phiSLOffset() {
0065   // sl1 offset respect to sl3 - in Front End view!!
0066   float x1 = tubePosInCh(1, 1, 1).x();
0067   float x3 = tubePosInCh(3, 1, 1).x();
0068   float offset = x1 - x3;
0069   //   if(posFE(1)==1)        // Obsolete in
0070   //     offset = - offset;   // CMSSW
0071 
0072   return offset;
0073 }
0074 
0075 /* OBSOLETE - MAYBE - 19/06/06
0076 int
0077 DTTrigGeom::layerFEStaggering(int nsl, int nlay) const {
0078 
0079   NB the staggering is in FE view!
0080   return cell staggering respect to first wire in layer 1 in cell units
0081   the following is the default: staggering 0 of each layer
0082      +---------+---------+---------+
0083      | 1  o    | 2  o    | 3  o    |
0084      +----+----+----+----+----+----+
0085           | 1  o    |  2 o    |
0086      +----+----+----+----+----+
0087      | 1  o    | 2  o    |
0088      +----+----+----+----+----+
0089           | 1  o    | 2  o    |
0090           +---------+---------+   ------------> x (y coming out of video) in SL
0091 frame
0092 
0093 
0094   int stag = 0;
0095 
0096   if(station()==4 && nsl==2){
0097     std::cout << "No theta superlayer in station 4!" << std::endl;
0098     return 0;
0099   }
0100   //position in chamber of wire 1 in layer 1
0101   LocalPoint posInCh_lay1      = tubePosInCh(nsl,1,1);
0102   //position in chamber of wire 1 in layer nlay
0103   int n1stwire = (nlay==4 ? 2 : 1);
0104   LocalPoint posInCh_lay       = tubePosInCh(nsl,nlay,n1stwire);
0105 
0106  cout << endl;
0107  cout << nlay << posInCh_lay1 << posInCh_lay << endl;
0108  cout <<endl ;
0109 
0110 
0111   //NB PITCH-0.01 for computer approximation bug
0112   if(nsl==2){//SL2: first wire is toward positive y
0113     stag = static_cast<int>((-posInCh_lay.y()+posInCh_lay1.y())/(_PITCH-0.01) +
0114 0.5*(fmod(nlay,2.)==0?1:0));
0115   }
0116   else{//SL1 and SL3: first wire is toward negative x
0117           if (nlay==4) {
0118                   stag =
0119 static_cast<int>((+posInCh_lay.x()-posInCh_lay1.x()+_PITCH)/(_PITCH-0.01) +
0120 0.5*(fmod(nlay,2.)==0?1:0));
0121           }
0122           else {
0123                 stag =
0124 static_cast<int>((+posInCh_lay.x()-posInCh_lay1.x())/(_PITCH-0.01) +
0125 0.5*(fmod(nlay,2.)==0?1:0));
0126           }
0127   }
0128 
0129   //FEP=1 means in y negative in layer frame
0130   const DTLayer* lay  =
0131 _stat->superLayer(DTSuperLayerId(statId(),nsl))->layer(DTLayerId(statId(),nsl,nlay));
0132   const DTLayer* lay1 =
0133 _stat->superLayer(DTSuperLayerId(statId(),nsl))->layer(DTLayerId(statId(),nsl,1));
0134 
0135   if(lay->getFEPosition()==1){ //FE staggering is reverted //MODIFICARE
0136 DOPO!!!!!! int nWire  = lay->specificTopology().channels(); int nWire1 =
0137 lay1->specificTopology().channels(); stag = - nWire + nWire1 - stag +
0138 (fmod(nlay,2.)==0?1:0);
0139   }
0140   return stag;
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     // obsolete 19/06/2006  const DTLayer* lay =
0150     // _stat->superLayer(DTSuperLayerId(statId(),nsl))->layer(DTLayerId(statId(),nsl,nlay));
0151 
0152     /* obsolete 19/6/06
0153      if(lay->getFEPosition()==0)         //FE is in Y negative: opposite
0154     numbering nch = lay->specificTopology().channels() - ntube + 1;
0155     //   if(lay->getFEPosition()==1)         //FE is in Y positive: same
0156     numbering digi-trig
0157     //     nch = ntube;
0158     //  }
0159     */
0160     // in new geometry depends on SL: theta tube numbering is reverted wrt
0161     // hardware
0162     nch = ntube;
0163     /*  if(nsl==2){
0164                     nch = lay->specificTopology().channels() - ntube + 1;
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   // obsolete 19/06/2006 GlobalPoint  posInCMS = lay->toGlobal(posInLayer);
0183 
0184   /* cout <<endl;
0185    cout << "tube " << ntube << " nlay " << nlay << endl;
0186    cout << "posinlayer " << posInLayer << "posinchamb " << posInChamber <<
0187    "posinCMS " << posInCMS << endl;*/
0188 
0189   return posInChamber;
0190 }
0191 
0192 int DTTrigGeom::posFE(int sl) const {
0193   if (station() != 4 || sl != 2) {
0194     // obsolete 19/0602006 const DTLayer* lay  =
0195     // _stat->superLayer(DTSuperLayerId(statId(),sl))->layer(DTLayerId(statId(),sl,1));
0196     return 1 /*lay->getFEPosition()*/;
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   // Geometrical constants of chamber
0210   // Cell width (cm)
0211   _PITCH = 4.2;
0212   // Cell height (cm)
0213   _H = 1.3;
0214   // azimuthal angle of normal to the chamber
0215   _PHICH = _stat->surface().toGlobal(LocalVector(0, 0, -1)).phi();
0216 
0217   // superlayer positions and number of cells
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) {  // No theta SL in MB4
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();  // - 1.5 * _H;
0229       // LocalPoint posInLayer=l1[i]->layType()->getWire(1)->positionInLayer();
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   // debugging
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     // if(wheel()==2&&sector()==2){ // only 1 sector-wheel
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   // end debugging
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   // chamber id
0318   int wh = wheel();
0319   int st = station();
0320   int se = sector();
0321 
0322   // open txt file
0323   string name = "Lut_from_CMSSW_geom";
0324   /* name += "_wh_";
0325    if(wh<0)
0326          name += "-";
0327    name += abs(wh) + '0';
0328    name += "_st_";
0329    name += st + '0';
0330    name += "_se_";
0331    if(se<10)
0332          name += se + '0';
0333    else
0334    {
0335          name += 1 + '0';
0336          name += (se-10) + '0';
0337    }
0338    */
0339   name += ".txt";
0340 
0341   ofstream fout;
0342   fout.open(name.c_str(), ofstream::app);
0343 
0344   // *** dump file header
0345   //  fout << "Identification: wheel\t" << wh;
0346   //  fout << "\tstation\t" << st;
0347   //  fout << "\tsector\t" << se;
0348   fout << wh;
0349   fout << "\t" << st;
0350   fout << "\t" << se;
0351 
0352   // SL shift
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   //  std::cout << " SL shift " << SL_shift << std::endl;
0357 
0358   // traco 1 and 2 global position
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   // std::cout << " tr1 x " << traco_1.x() << " tr2 x " << traco_2.x() <<
0364   // std::endl;
0365 
0366   float d;
0367   float xcn;
0368   int xcn_sign;
0369   GlobalPoint pp = _stat->toGlobal(LocalPoint(0, 0, ZcenterSL()));
0370   // std::cout << "Position: x=" << pp.x() << "cm, y=" << pp.y() << "cm, z=" <<
0371   // pp.z() << std::endl;
0372 
0373   if (sector() == 1 || sector() == 7) {
0374     d = fabs(traco_1.x());
0375     xcn = fabs(traco_1.y());
0376     // 110208 SV comment: this was inserted for a TRACO hardware bug
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     // 110208 SV comment: this was inserted for a TRACO hardware bug
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   // std::cout << " d " << d << " xcn " << xcn << " sign " << xcn_sign <<
0401   // std::endl;
0402   // fout << "\td\t" << d << "\txcn\t" << xcn << "\t";
0403   // fout << "btic\t" << btic << "\t";
0404 
0405   // *** dump TRACO LUT command
0406   fout << "\tA8";
0407   // short int btic = 31;
0408   // cout << "CHECK BTIC " << btic << endl;
0409   short int Low_byte = (btic & 0x00FF);  // output in hex bytes format with zero padding
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   // convert parameters from IEE32 float to DSP float format
0414   short int DSPmantissa = 0;
0415   short int DSPexp = 0;
0416 
0417   // d parameter conversion and dump
0418   IEEE32toDSP(d, DSPmantissa, DSPexp);
0419   Low_byte = (DSPmantissa & 0x00FF);  // output in hex bytes format with zero padding
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   // xnc parameter conversion and dump
0427   DSPmantissa = 0;
0428   DSPexp = 0;
0429   IEEE32toDSP(xcn, DSPmantissa, DSPexp);
0430   Low_byte = (DSPmantissa & 0x00FF);  // output in hex bytes format with zero padding
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   // sign bits
0438   Low_byte = (xcn_sign & 0x00FF);  // output in hex bytes format with zero padding
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 // A. Gozzelino May 11th 2012: Old and wrong definition
0449 void
0450 DTTrigGeom::IEEE32toDSP(float f, short int & DSPmantissa, short int & DSPexp)
0451 {
0452   long int *pl=0, lm;
0453   bool sign=false;
0454 
0455   DSPmantissa = 0;
0456   DSPexp = 0;
0457 
0458   if( f!=0.0 )
0459   {
0460         memcpy(pl,&f,sizeof(float));
0461 
0462         if((*pl & 0x80000000)!=0)
0463                 sign=true;
0464         lm = ( 0x800000 | (*pl & 0x7FFFFF)); // [1][23bit mantissa]
0465         lm >>= 9; //reduce to 15bits
0466         lm &= 0x7FFF;
0467         DSPexp = ((*pl>>23)&0xFF)-126;
0468         DSPmantissa = (short)lm;
0469         if(sign)
0470                 DSPmantissa = - DSPmantissa;  // convert negative value in 2.s
0471 complement
0472 
0473   }
0474   return;
0475 }
0476 */
0477 
0478 //*******************
0479 // A.Gozzelino May 11th 2012: bug fix in method IEEE32toDSP
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));  // [1][23bit mantissa]
0497     lm >>= 9;                           // reduce to 15bits
0498     lm &= 0x7FFF;
0499     DSPexp = ((pl >> 23) & 0xFF) - 126;
0500     DSPmantissa = (short)lm;
0501     if (sign)
0502       DSPmantissa = -DSPmantissa;  // convert negative value in 2.s complement
0503   }
0504   return;
0505 }
0506 //********************** end bug fix ****************
0507 
0508 LocalPoint DTTrigGeom::localPosition(const DTBtiId id) const {
0509   /* obsolete!
0510     float x = 0;
0511     float y = 0;
0512     float z = ZSL(id.superlayer());
0513     if(id.superlayer()==2){
0514       // SL 2: Reverse numbering -------V
0515       y = Xwire1BTI1SL(id.superlayer()) - ((float)(id.bti()-1)-0.5)*cellPitch();
0516     } else {
0517       x = Xwire1BTI1SL(id.superlayer()) + ((float)(id.bti()-1)-0.5)*cellPitch();
0518     }
0519   */
0520 
0521   // NEWGEO
0522   /*  int nsl = id.superlayer();
0523     int tube = mapTubeInFEch(nsl,1,id.bti());
0524     LocalPoint p = tubePosInCh(nsl,1,tube);
0525     //traslation because z axes is in middle of SL, x/y axes on left I of first
0526     cell
0527 
0528     LocalPoint p1 = tubePosInCh (nsl,1,1);
0529     LocalPoint p2 = tubePosInCh (nsl,2,1);
0530     cout << "nbti " << id.bti() << " tube " << tube << " localpoint" << p <<
0531     endl; cout << "localpoint layer 1" << p1  << " localpoint layer 2" << p2 <<
0532     endl;
0533 
0534     float xt = 0;
0535     float yt = 0;
0536     float zt = - cellH() * 3./2.;
0537     if(nsl==2)
0538       yt = - cellPitch()/2.;
0539     else
0540       xt = + cellPitch()/2.;
0541 
0542     if(posFE(nsl)==0){//FE in positive y
0543         xt = - xt;
0544         yt = - yt;
0545     }
0546 
0547     cout << "localpoint " << p << ' '  << xt << ' ' << yt << endl;
0548 
0549     return LocalPoint(p.x()+xt,p.y()+yt,p.z()+zt);*/
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   // LocalPoint posInLayer1(localX+xt,yt,0); //Correction now y is left I of
0559   // first cell of layer 1 y=0 and z in the middle of SL,
0560   LocalPoint posInLayer1(localX + xt, 0, zt);
0561   LocalPoint posInChamber = _stat->surface().toLocal(lay->toGlobal(posInLayer1));
0562   // GlobalPoint posInCMS = lay->toGlobal(posInLayer1);
0563 
0564   /* cout <<endl;
0565   cout << "tube " << ntube << " nlay " << nlay << endl;
0566   cout << "posinlayer " << posInLayer1 << "posinchamb " << posInChamber <<
0567   "posinCMS " << posInCMS << endl;*/
0568 
0569   return posInChamber;
0570 }
0571 
0572 LocalPoint DTTrigGeom::localPosition(const DTTracoId id) const {
0573   /* obsolete
0574     float x = Xwire1BTI1SL(1) +
0575       ( ( (float)(id.traco()) - 0.5 ) * DTConfig::NBTITC - 0.5 )*cellPitch();
0576     // half cell shift in SL1 of MB1 (since cmsim116)
0577     if(station()==1) x -= 0.5*cellPitch();
0578     float y = 0;
0579     float z = ZcenterSL();
0580   */
0581   // NEWGEO
0582   // position of first BTI in sl 3 on X
0583   float x = localPosition(DTBtiId(DTSuperLayerId(wheel(), station(), sector(), 3), 1)).x();
0584   // 10/7/06 May be not needed anymore in new geometry
0585   //   if(posFE(3)==1)
0586   //     x -= (id.traco()-2)*DTConfig::NBTITC * cellPitch();
0587   //   if(posFE(3)==0)
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 }