Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:07:54

0001 /** \file
0002  *
0003  *  \author R. Bellan  - INFN Torino
0004  */
0005 
0006 #include "Geometry/DTGeometry/interface/DTTopology.h"
0007 #include <FWCore/Utilities/interface/Exception.h>
0008 
0009 #include <iostream>
0010 
0011 // FIXME now put by hand, check the number!
0012 
0013 const float DTTopology::theWidth = 4.2;   // cm
0014 const float DTTopology::theHeight = 1.3;  // cm ...
0015 
0016 const float DTTopology::IBeamWingThickness = 0.13;  // cm
0017 const float DTTopology::IBeamWingLength = 0.635;    // cm
0018 
0019 const float DTTopology::plateThickness = 0.15;  // aluminium plate:  1.5 mm
0020 const float DTTopology::IBeamThickness = 0.13;  // I-beam thickness: 1.3 mm
0021 
0022 DTTopology::DTTopology(int firstWire, int nChannels, float semilenght)
0023     : theFirstChannel(firstWire), theNChannels(nChannels), theLength(semilenght * 2) {
0024   theOffSet = Local2DPoint(-theNChannels / 2. * theWidth, -theLength / 2.);
0025 
0026 #ifdef VERBOSE
0027   cout << "Constructing DTTopology with:" << endl
0028        << "number of wires = " << theNChannels << ", first wire number = " << theFirstChannel << endl
0029        << ", width = " << theWidth << ", height = " << theHeight << ", length = " << theLength << endl;
0030 #endif
0031 }
0032 
0033 float DTTopology::sensibleWidth() const { return theWidth - IBeamThickness; }
0034 
0035 float DTTopology::sensibleHeight() const { return theHeight - plateThickness; }
0036 
0037 LocalPoint DTTopology::localPosition(const MeasurementPoint& mp) const {
0038   return LocalPoint((mp.x() - theFirstChannel) * theWidth + theOffSet.x(), (1 - mp.y()) * theLength + theOffSet.y());
0039 }
0040 
0041 LocalError DTTopology::localError(const MeasurementPoint& /*mp*/, const MeasurementError& me) const {
0042   return LocalError(me.uu() * (theWidth * theWidth), 0, me.vv() * (theLength * theLength));
0043 }
0044 
0045 MeasurementPoint DTTopology::measurementPosition(const LocalPoint& lp) const {
0046   return MeasurementPoint(static_cast<int>((lp.x() - theOffSet.x()) / theWidth + theFirstChannel),
0047                           1 - (lp.y() - theOffSet.y()) / theLength);
0048 }
0049 
0050 MeasurementError DTTopology::measurementError(const LocalPoint& /*lp*/, const LocalError& le) const {
0051   return MeasurementError(le.xx() / (theWidth * theWidth), 0, le.yy() / (theLength * theLength));
0052 }
0053 
0054 int DTTopology::channel(const LocalPoint& lp) const {
0055   return static_cast<int>((lp.x() - theOffSet.x()) / theWidth + theFirstChannel);
0056 }
0057 
0058 // return the x wire position in the layer, starting from its wire number.
0059 float DTTopology::wirePosition(int wireNumber) const {
0060   if (!isWireValid(wireNumber))  //- (theFirstChannel-1) <= 0. || wireNumber > lastChannel() )
0061     throw cms::Exception("InvalidWireNumber")
0062         << "DTTopology::wirePosition:"
0063         << " Requested wire number: " << wireNumber << " ,but the first wire number is " << theFirstChannel
0064         << " and the last wire number is " << lastChannel() << std::endl;
0065   else
0066     return (wireNumber - (theFirstChannel - 1) - 0.5) * theWidth + theOffSet.x();
0067 }
0068 
0069 /*
0070 // return the x wire position in the layer r.f., starting from its wire number.
0071 float DTTopology::wirePosition(int wireNumber) const{
0072   int layerCoord = theNChannels - wireNumber + theFirstChannel;
0073   return  (layerCoord - 0.5)*theWidth + theOffSet.x();
0074 }
0075 */
0076 
0077 //New cell geometry
0078 DTTopology::Side DTTopology::onWhichBorder(float x, float /*y*/, float z) const {
0079   // epsilon = Tolerance to determine if a hit starts/ends on the cell border.
0080   // Current value comes from CMSIM, where hit position is
0081   // always ~10um far from surface. For OSCAR the discrepancy is < 1um.
0082   const float epsilon = 0.0015;  // 15 um
0083 
0084   // with new geometry the cell shape is not rectangular, but is a
0085   // rectangular with the I-beam "Wing" subtracted.
0086   // The height of the Wing is 1.0 mm and the length is 6.35 mm: these 4
0087   // volumens must be taken into account when the border is computed
0088 
0089   Side side = none;
0090 
0091   if (fabs(z) > (sensibleHeight() / 2. - epsilon) ||
0092       (fabs(x) > (sensibleWidth() / 2. - IBeamWingLength - epsilon) &&
0093        fabs(z) > (sensibleHeight() / 2. - IBeamWingThickness - epsilon))) {  //FIXME
0094 
0095     if (z > 0.)
0096       side = zMax;  // This is currently the INNER surface.
0097     else
0098       side = zMin;
0099   }
0100 
0101   else if (fabs(x) > (sensibleWidth() / 2. - epsilon)) {
0102     if (x > 0.)
0103       side = xMax;
0104     else
0105       side = xMin;
0106   }  // FIXME: else if ymax, ymin...
0107 
0108   return side;
0109 }
0110 
0111 //Old geometry of the DT
0112 DTTopology::Side DTTopology::onWhichBorder_old(float x, float /*y*/, float z) const {
0113   // epsilon = Tolerance to determine if a hit starts/ends on the cell border.
0114   // Current value comes from CMSIM, where hit position is
0115   // always ~10um far from surface. For OSCAR the discrepancy is < 1um.
0116   const float epsilon = 0.0015;  // 15 um
0117 
0118   Side side = none;
0119 
0120   if (fabs(z) > (sensibleHeight() / 2. - epsilon)) {
0121     if (z > 0.) {
0122       side = zMax;  // This is currently the INNER surface.
0123     } else {
0124       side = zMin;
0125     }
0126   } else if (fabs(x) > (sensibleWidth() / 2. - epsilon)) {
0127     if (x > 0.) {
0128       side = xMax;
0129     } else {
0130       side = xMin;
0131     }
0132   }  // FIXME: else if ymax, ymin...
0133 
0134   return side;
0135 }