Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:30:45

0001 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0002 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0003 #include "Geometry/CommonTopologies/interface/PixelGeomDetUnit.h"
0004 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
0005 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 
0008 #include "L1Trigger/TrackFindingTMTT/interface/TrackerModule.h"
0009 
0010 #include <iostream>
0011 #include <sstream>
0012 #include <mutex>
0013 
0014 using namespace std;
0015 
0016 namespace tmtt {
0017 
0018   namespace {
0019     std::once_flag printOnce;
0020   }
0021 
0022   const float TrackerModule::invRoot12 = sqrt(1. / 12.);
0023 
0024   //=== Get info about tracker module (where detId is ID of lower sensor in stacked module).
0025 
0026   TrackerModule::TrackerModule(const TrackerGeometry* trackerGeometry,
0027                                const TrackerTopology* trackerTopology,
0028                                const ModuleTypeCfg& moduleTypeCfg,
0029                                const DetId& detId)
0030       : moduleTypeCfg_(moduleTypeCfg) {
0031     detId_ = detId;                                 // Det ID of lower sensor in stacked module.
0032     stackedDetId_ = trackerTopology->stack(detId);  // Det ID of stacked module.
0033 
0034     // Get min & max (r,phi,z) coordinates of the centre of the two sensors containing this stub.
0035     const GeomDetUnit* det0 = trackerGeometry->idToDetUnit(detId);
0036     const GeomDetUnit* det1 = trackerGeometry->idToDetUnit(trackerTopology->partnerDetId(detId));
0037     specDet_ = dynamic_cast<const PixelGeomDetUnit*>(det0);
0038     specTopol_ = dynamic_cast<const PixelTopology*>(&(specDet_->specificTopology()));
0039 
0040     float R0 = det0->position().perp();
0041     float R1 = det1->position().perp();
0042     float PHI0 = det0->position().phi();
0043     float PHI1 = det1->position().phi();
0044     float Z0 = det0->position().z();
0045     float Z1 = det1->position().z();
0046     moduleMinR_ = std::min(R0, R1);
0047     moduleMaxR_ = std::max(R0, R1);
0048     moduleMinPhi_ = std::min(PHI0, PHI1);
0049     moduleMaxPhi_ = std::max(PHI0, PHI1);
0050     moduleMinZ_ = std::min(Z0, Z1);
0051     moduleMaxZ_ = std::max(Z0, Z1);
0052 
0053     // Note if modules are flipped back-to-front.
0054     outerModuleAtSmallerR_ = (det0->position().mag() > det1->position().mag());
0055 
0056     // Note if module is PS or 2S, and whether in barrel or endcap.
0057     // From Geometry/TrackerGeometryBuilder/README.md
0058     psModule_ = (trackerGeometry->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP);
0059     barrel_ = detId.subdetId() == StripSubdetector::TOB || detId.subdetId() == StripSubdetector::TIB;
0060 
0061     // Encode layer ID (barrel layers: 1-6, endcap disks: 11-15 + 21-25)
0062     if (barrel_) {
0063       layerId_ = trackerTopology->layer(detId);  // barrel layer 1-6 encoded as 1-6
0064     } else {
0065       layerId_ = 10 * trackerTopology->side(detId) + trackerTopology->tidWheel(detId);
0066     }
0067     // Get reduced layer ID (in range 1-7), requiring only 3 bits for firmware.
0068     layerIdReduced_ = TrackerModule::calcLayerIdReduced(layerId_);
0069 
0070     // Note module ring in endcap
0071     endcapRing_ = barrel_ ? 0 : trackerTopology->tidRing(detId);
0072     if (not barrel_) {
0073       // Apply bodge, since Topology class annoyingly starts ring count at 1, even in endcap wheels where
0074       // inner rings are absent.
0075       unsigned int iWheel = trackerTopology->tidWheel(detId);
0076       if (iWheel >= 3 && iWheel <= 5)
0077         endcapRing_ += 3;
0078     }
0079 
0080     // Note if tilted barrel module & get tilt angle (in range 0 to PI).
0081     tiltedBarrel_ = barrel_ && (trackerTopology->tobSide(detId) != BarrelModuleType::flat);
0082     float deltaR = std::abs(R1 - R0);
0083     float deltaZ = (R1 - R0 > 0) ? (Z1 - Z0) : -(Z1 - Z0);
0084     tiltAngle_ = atan(deltaR / deltaZ);
0085 
0086     // Get sensor strip or pixel pitch using innermost sensor of pair.
0087 
0088     const Bounds& bounds = det0->surface().bounds();
0089     sensorWidth_ = bounds.width();  // Width of sensitive region of sensor (= stripPitch * nStrips).
0090     sensorSpacing_ = sqrt((moduleMaxR_ - moduleMinR_) * (moduleMaxR_ - moduleMinR_) +
0091                           (moduleMaxZ_ - moduleMinZ_) * (moduleMaxZ_ - moduleMinZ_));
0092     nStrips_ = specTopol_->nrows();  // No. of strips in sensor
0093     std::pair<float, float> pitch = specTopol_->pitch();
0094     stripPitch_ = pitch.first;    // Strip pitch (or pixel pitch along shortest axis)
0095     stripLength_ = pitch.second;  //  Strip length (or pixel pitch along longest axis)
0096 
0097     // Get module type ID defined by firmware.
0098 
0099     moduleTypeID_ = TrackerModule::calcModuleType(stripPitch_, sensorSpacing_, barrel_, tiltedBarrel_, psModule_);
0100   }
0101 
0102   //=== Calculate reduced layer ID (in range 1-7), for  packing into 3 bits to simplify the firmware.
0103 
0104   unsigned int TrackerModule::calcLayerIdReduced(unsigned int layerId) {
0105     // Don't bother distinguishing two endcaps, as no track can have stubs in both.
0106     unsigned int lay = (layerId < 20) ? layerId : layerId - 10;
0107 
0108     // No genuine track can have stubs in both barrel layer 6 and endcap disk 11 etc., so merge their layer IDs.
0109     if (lay == 6)
0110       lay = 11;
0111     if (lay == 5)
0112       lay = 12;
0113     if (lay == 4)
0114       lay = 13;
0115     if (lay == 3)
0116       lay = 15;
0117     // At this point, the reduced layer ID can have values of 1, 2, 11, 12, 13, 14, 15. So correct to put in range 1-7.
0118     if (lay > 10)
0119       lay -= 8;
0120 
0121     if (lay < 1 || lay > 7)
0122       throw cms::Exception("LogicError") << "TrackerModule: Reduced layer ID out of expected range";
0123 
0124     return lay;
0125   }
0126 
0127   //=== Get module type ID defined by firmware.
0128 
0129   unsigned int TrackerModule::calcModuleType(
0130       float pitch, float space, bool barrel, bool tiltedBarrel, bool psModule) const {
0131     // Calculate unique module type ID, allowing sensor pitch/seperation of module to be determined in FW.
0132 
0133     unsigned int moduleType = 999;
0134     constexpr float tol = 0.001;  // Tolerance
0135 
0136     for (unsigned int i = 0; i < moduleTypeCfg_.pitchVsType.size(); i++) {
0137       if (std::abs(pitch - moduleTypeCfg_.pitchVsType[i]) < tol &&
0138           std::abs(space - moduleTypeCfg_.spaceVsType[i]) < tol && barrel == moduleTypeCfg_.barrelVsType[i] &&
0139           tiltedBarrel == moduleTypeCfg_.tiltedVsType[i] && psModule == moduleTypeCfg_.psVsType[i]) {
0140         moduleType = i;
0141       }
0142     }
0143 
0144     if (moduleType == 999) {
0145       std::stringstream text;
0146       text << "WARNING: TrackerModule found tracker module type unknown to firmware: pitch=" << pitch
0147            << " separation=" << space << " barrel=" << barrel << " tilted=" << tiltedBarrel << " PS=" << psModule;
0148       std::call_once(
0149           printOnce, [](string t) { edm::LogWarning("L1track") << t; }, text.str());
0150     }
0151     return moduleType;
0152   }
0153 }  // namespace tmtt