File indexing completed on 2024-04-06 12:15:16
0001
0002 #include "FWCore/Framework/interface/Frameworkfwd.h"
0003 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0004
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/EventSetup.h"
0007 #include "FWCore/Framework/interface/ESHandle.h"
0008 #include "FWCore/Framework/interface/MakerMacros.h"
0009
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "Geometry/MTDGeometryBuilder/interface/MTDGeometry.h"
0012 #include "Geometry/Records/interface/MTDDigiGeometryRecord.h"
0013 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
0014 #include "Geometry/MTDGeometryBuilder/interface/MTDGeomDetType.h"
0015 #include "Geometry/MTDGeometryBuilder/interface/RectangularMTDTopology.h"
0016
0017 #include "DataFormats/ForwardDetId/interface/MTDDetId.h"
0018 #include "DataFormats/ForwardDetId/interface/BTLDetId.h"
0019 #include "DataFormats/ForwardDetId/interface/ETLDetId.h"
0020 #include "Geometry/MTDGeometryBuilder/interface/MTDGeomDetUnit.h"
0021 #include "DataFormats/GeometrySurface/interface/MediumProperties.h"
0022 #include "DataFormats/GeometrySurface/interface/RectangularPlaneBounds.h"
0023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0024
0025 #include "DataFormats/Math/interface/Rounding.h"
0026
0027 #include <fstream>
0028
0029 #include "CLHEP/Random/RandFlat.h"
0030
0031
0032
0033 class MTDDigiGeometryAnalyzer : public edm::one::EDAnalyzer<> {
0034 public:
0035 explicit MTDDigiGeometryAnalyzer(const edm::ParameterSet&);
0036 ~MTDDigiGeometryAnalyzer() override = default;
0037
0038 void beginJob() override {}
0039 void analyze(edm::Event const& iEvent, edm::EventSetup const&) override;
0040 void endJob() override {}
0041
0042 private:
0043 void analyseRectangle(const GeomDetUnit& det);
0044 void checkRotation(const GeomDetUnit& det);
0045 void checkRectangularMTDTopology(const RectangularMTDTopology&);
0046 void checkPixelsAcceptance(const GeomDetUnit& det);
0047
0048 std::stringstream sunitt;
0049
0050 edm::ESGetToken<MTDGeometry, MTDDigiGeometryRecord> mtdgeoToken_;
0051 };
0052
0053 using cms_rounding::roundIfNear0, cms_rounding::roundVecIfNear0;
0054
0055 MTDDigiGeometryAnalyzer::MTDDigiGeometryAnalyzer(const edm::ParameterSet& iConfig) {
0056 mtdgeoToken_ = esConsumes<MTDGeometry, MTDDigiGeometryRecord>();
0057 }
0058
0059
0060 void MTDDigiGeometryAnalyzer::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0061
0062
0063
0064 auto pDD = iSetup.getTransientHandle(mtdgeoToken_);
0065 edm::LogInfo("MTDDigiGeometryAnalyzer")
0066 << "Geometry node for MTDGeom is " << &(*pDD) << "\n"
0067 << " # detectors = " << pDD->detUnits().size() << "\n"
0068 << " # types = " << pDD->detTypes().size() << "\n"
0069 << " # BTL dets = " << pDD->detsBTL().size() << "\n"
0070 << " # ETL dets = " << pDD->detsETL().size() << "\n"
0071 << " # layers " << pDD->geomDetSubDetector(1) << " = " << pDD->numberOfLayers(1) << "\n"
0072 << " # layers " << pDD->geomDetSubDetector(2) << " = " << pDD->numberOfLayers(2) << "\n";
0073 sunitt << std::fixed << std::setw(7) << pDD->detUnits().size() << std::setw(7) << pDD->detTypes().size() << "\n";
0074 for (auto const& it : pDD->detUnits()) {
0075 if (dynamic_cast<const MTDGeomDetUnit*>((it)) != nullptr) {
0076 const BoundPlane& p = (dynamic_cast<const MTDGeomDetUnit*>((it)))->specificSurface();
0077 const MTDDetId mtdId(it->geographicalId());
0078 std::stringstream moduleLabel;
0079 if (mtdId.mtdSubDetector() == 1) {
0080 const BTLDetId btlId(it->geographicalId());
0081 moduleLabel << " BTL side " << btlId.mtdSide() << " Rod " << btlId.mtdRR() << " type/RU " << btlId.modType()
0082 << "/" << btlId.runit() << " mod " << btlId.module();
0083 } else if (mtdId.mtdSubDetector() == 2) {
0084 const ETLDetId etlId(it->geographicalId());
0085 moduleLabel << " ETL side " << mtdId.mtdSide() << " Disc/Side/Sector " << etlId.nDisc() << " "
0086 << etlId.discSide() << " " << etlId.sector();
0087 } else {
0088 edm::LogWarning("MTDDigiGeometryanalyzer") << (it->geographicalId()).rawId() << " unknown MTD subdetector!";
0089 }
0090 edm::LogVerbatim("MTDDigiGeometryAnalyzer")
0091 << "---------------------------------------------------------- \n"
0092 << it->geographicalId().rawId() << moduleLabel.str() << " RadLeng Pixel " << p.mediumProperties().radLen()
0093 << " Xi Pixel " << p.mediumProperties().xi();
0094
0095 const GeomDetUnit theDet = *(dynamic_cast<const MTDGeomDetUnit*>(it));
0096 analyseRectangle(theDet);
0097 }
0098 }
0099
0100 for (auto const& it : pDD->detTypes()) {
0101 if (dynamic_cast<const MTDGeomDetType*>((it)) != nullptr) {
0102 const PixelTopology& p = (dynamic_cast<const MTDGeomDetType*>((it)))->specificTopology();
0103 const RectangularMTDTopology& topo = static_cast<const RectangularMTDTopology&>(p);
0104 auto pitchval = topo.pitch();
0105 edm::LogVerbatim("MTDDigiGeometryAnalyzer")
0106 << "\n Subdetector " << it->subDetector() << " MTD Det " << it->name() << "\n"
0107 << " Rows " << topo.nrows() << " Columns " << topo.ncolumns() << " ROCS X " << topo.rocsX()
0108 << " ROCS Y " << topo.rocsY() << " Rows/ROC " << topo.rowsperroc() << " Cols/ROC " << topo.colsperroc()
0109 << " Pitch X " << pitchval.first << " Pitch Y " << pitchval.second << " Sensor Interpad X "
0110 << topo.gapxInterpad() << " Sensor Interpad Y " << topo.gapyInterpad() << " Sensor Border X "
0111 << topo.gapxBorder() << " Sensor Border Y " << topo.gapyBorder();
0112 sunitt << std::fixed << std::setw(7) << it->subDetector() << std::setw(4) << topo.nrows() << std::setw(4)
0113 << topo.ncolumns() << std::setw(4) << std::setw(4) << topo.rocsX() << std::setw(4) << topo.rocsY()
0114 << std::setw(4) << topo.rowsperroc() << std::setw(4) << topo.colsperroc() << std::setw(10)
0115 << pitchval.first << std::setw(10) << pitchval.second << std::setw(10) << topo.gapxInterpad()
0116 << std::setw(10) << topo.gapyInterpad() << std::setw(10) << topo.gapxBorder() << std::setw(10)
0117 << topo.gapyBorder() << "\n";
0118 checkRectangularMTDTopology(topo);
0119 }
0120 }
0121
0122 edm::LogInfo("MTDDigiGeometryAnalyzer") << "Acceptance of BTL module:";
0123 auto const& btldet = *(dynamic_cast<const MTDGeomDetUnit*>(pDD->detsBTL().front()));
0124 checkPixelsAcceptance(btldet);
0125 edm::LogInfo("MTDDigiGeometryAnalyzer") << "Acceptance of ETL module:";
0126 auto const& etldet = *(dynamic_cast<const MTDGeomDetUnit*>(pDD->detsETL().front()));
0127 checkPixelsAcceptance(etldet);
0128
0129 edm::LogInfo("MTDDigiGeometryAnalyzer") << "Additional MTD geometry content:"
0130 << "\n"
0131 << " # dets = " << pDD->dets().size() << "\n"
0132 << " # detUnitIds = " << pDD->detUnitIds().size() << "\n"
0133 << " # detIds = " << pDD->detIds().size() << "\n";
0134 sunitt << std::fixed << std::setw(7) << pDD->dets().size() << std::setw(7) << pDD->detUnitIds().size() << std::setw(7)
0135 << pDD->detIds().size() << "\n";
0136
0137 edm::LogVerbatim("MTDUnitTest") << sunitt.str();
0138 }
0139
0140 void MTDDigiGeometryAnalyzer::checkRectangularMTDTopology(const RectangularMTDTopology& topo) {
0141 std::stringstream pixelinfo;
0142 pixelinfo << "Pixel center location:\n";
0143 LocalPoint center(0, 0, 0);
0144 for (int r = 0; r < topo.nrows(); r++) {
0145 for (int c = 0; c < topo.ncolumns(); c++) {
0146 sunitt << r << " " << c << " " << topo.pixelToModuleLocalPoint(center, r, c) << "\n";
0147 pixelinfo << r << " " << c << " " << topo.pixelToModuleLocalPoint(center, r, c) << "\n";
0148 }
0149 }
0150 edm::LogVerbatim("MTDDigiGeometryAnalyzer") << pixelinfo.str();
0151 }
0152
0153 void MTDDigiGeometryAnalyzer::analyseRectangle(const GeomDetUnit& det) {
0154 const double safety = 0.9999;
0155
0156 const Bounds& bounds = det.surface().bounds();
0157 const RectangularPlaneBounds* tb = dynamic_cast<const RectangularPlaneBounds*>(&bounds);
0158 if (tb == nullptr)
0159 return;
0160
0161 const GlobalPoint& pos = det.position();
0162 double length = tb->length();
0163 double width = tb->width();
0164 double thickness = tb->thickness();
0165
0166 GlobalVector yShift = det.surface().toGlobal(LocalVector(0, 0, safety * length / 2.));
0167 GlobalPoint outerMiddle = pos + yShift;
0168 GlobalPoint innerMiddle = pos + (-1. * yShift);
0169 if (outerMiddle.perp() < innerMiddle.perp())
0170 std::swap(outerMiddle, innerMiddle);
0171
0172 auto fround = [&](double in) {
0173 std::stringstream ss;
0174 ss << std::fixed << std::setw(14) << roundIfNear0(in);
0175 return ss.str();
0176 };
0177
0178 auto fvecround = [&](GlobalPoint vecin) {
0179 std::stringstream ss;
0180 ss << std::fixed << std::setw(14) << roundVecIfNear0(vecin);
0181 return ss.str();
0182 };
0183
0184 edm::LogVerbatim("MTDDigiGeometryAnalyzer")
0185 << "Det at pos " << fvecround(pos) << " radius " << fround(std::sqrt(pos.x() * pos.x() + pos.y() * pos.y()))
0186 << " has length " << fround(length) << " width " << fround(width) << " thickness " << fround(thickness) << "\n"
0187 << "det center inside bounds? " << tb->inside(det.surface().toLocal(pos)) << "\n"
0188 << "outerMiddle " << fvecround(outerMiddle);
0189 sunitt << det.geographicalId().rawId() << fvecround(pos) << fround(length) << fround(width) << fround(thickness)
0190 << tb->inside(det.surface().toLocal(pos)) << fvecround(outerMiddle) << "\n";
0191
0192 checkRotation(det);
0193 }
0194
0195 void MTDDigiGeometryAnalyzer::checkRotation(const GeomDetUnit& det) {
0196 const double eps = std::numeric_limits<float>::epsilon();
0197 static int first = 0;
0198 if (first == 0) {
0199 edm::LogVerbatim("MTDDigiGeometryAnalyzer")
0200 << "numeric_limits<float>::epsilon() " << std::numeric_limits<float>::epsilon();
0201 first = 1;
0202 }
0203
0204 const Surface::RotationType& rot(det.surface().rotation());
0205 GlobalVector a(rot.xx(), rot.xy(), rot.xz());
0206 GlobalVector b(rot.yx(), rot.yy(), rot.yz());
0207 GlobalVector c(rot.zx(), rot.zy(), rot.zz());
0208 GlobalVector cref = a.cross(b);
0209 GlobalVector aref = b.cross(c);
0210 GlobalVector bref = c.cross(a);
0211 if ((a - aref).mag() > eps || (b - bref).mag() > eps || (c - cref).mag() > eps) {
0212 edm::LogWarning("MTDDigiGeometryAnalyzer")
0213 << " Rotation not good by cross product: " << (a - aref).mag() << ", " << (b - bref).mag() << ", "
0214 << (c - cref).mag() << " for det at pos " << det.surface().position();
0215 }
0216 if (fabs(a.mag() - 1.) > eps || fabs(b.mag() - 1.) > eps || fabs(c.mag() - 1.) > eps) {
0217 edm::LogWarning("MTDDigiGeometryAnalyzer") << " Rotation not good by bector mag: " << (a).mag() << ", " << (b).mag()
0218 << ", " << (c).mag() << " for det at pos " << det.surface().position();
0219 }
0220 }
0221
0222 void MTDDigiGeometryAnalyzer::checkPixelsAcceptance(const GeomDetUnit& det) {
0223 const Bounds& bounds = det.surface().bounds();
0224 const RectangularPlaneBounds* tb = dynamic_cast<const RectangularPlaneBounds*>(&bounds);
0225 if (tb == nullptr)
0226 return;
0227
0228 double length = tb->length();
0229 double width = tb->width();
0230 edm::LogVerbatim("MTDDigiGeometryAnalyzer") << "X (width) = " << width << " Y (length) = " << length;
0231
0232 const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(det.topology());
0233 const RectangularMTDTopology& topo = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
0234
0235 const size_t maxindex = 100000;
0236 size_t inpixel(0);
0237 for (size_t index = 0; index < maxindex; index++) {
0238 double ax = CLHEP::RandFlat::shoot(-width * 0.5, width * 0.5);
0239 double ay = CLHEP::RandFlat::shoot(-length * 0.5, length * 0.5);
0240 LocalPoint hit(ax, ay, 0);
0241 auto const indici = topo.pixelIndex(hit);
0242 assert(indici.first < topo.nrows() && indici.second < topo.ncolumns());
0243 if (topo.isInPixel(hit)) {
0244 inpixel++;
0245 }
0246 }
0247 double acc = (double)inpixel / (double)maxindex;
0248 double accerr = std::sqrt(acc * (1. - acc) / (double)maxindex);
0249 edm::LogVerbatim("MTDDigiGeometryAnalyzer") << "Acceptance: " << acc << " +/- " << accerr;
0250 }
0251
0252
0253 DEFINE_FWK_MODULE(MTDDigiGeometryAnalyzer);