Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:34:43

0001 #include "Alignment/TrackerAlignment/interface/AlignableTrackerBuilder.h"
0002 
0003 // Original Author:  Max Stark
0004 //         Created:  Thu, 13 Jan 2016 10:22:57 CET
0005 
0006 // geometry
0007 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0008 #include "Geometry/CommonDetUnit/interface/GluedGeomDet.h"
0009 #include "Geometry/CommonTopologies/interface/StackGeomDet.h"
0010 
0011 // alignment
0012 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
0013 #include "Alignment/CommonAlignment/interface/AlignableDetUnit.h"
0014 #include "Alignment/CommonAlignment/interface/AlignableCompositeBuilder.h"
0015 #include "Alignment/TrackerAlignment/interface/AlignableSiStripDet.h"
0016 #include "Alignment/TrackerAlignment/interface/AlignableStackDet.h"
0017 #include "Alignment/TrackerAlignment/interface/TrackerAlignableIndexer.h"
0018 
0019 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
0020 
0021 //=============================================================================
0022 //===   PUBLIC METHOD IMPLEMENTATION                                        ===
0023 //=============================================================================
0024 
0025 //_____________________________________________________________________________
0026 AlignableTrackerBuilder ::AlignableTrackerBuilder(const TrackerGeometry* trackerGeometry,
0027                                                   const TrackerTopology* trackerTopology)
0028     : trackerGeometry_(trackerGeometry),
0029       trackerTopology_(trackerTopology),
0030       alignableObjectId_(trackerGeometry, nullptr, nullptr, nullptr),
0031       alignableMap_(nullptr),
0032       trackerAlignmentLevelBuilder_(trackerTopology, trackerGeometry) {
0033   std::ostringstream ss;
0034 
0035   switch (alignableObjectId_.geometry()) {
0036     case AlignableObjectId::Geometry::RunI:
0037       ss << "RunI geometry";
0038       break;
0039     case AlignableObjectId::Geometry::PhaseI:
0040       ss << "PhaseI geometry";
0041       break;
0042     case AlignableObjectId::Geometry::PhaseII:
0043       ss << "PhaseII geometry";
0044       break;
0045     default:
0046       throw cms::Exception("LogicError") << "[AlignableTrackerBuilder] unknown version of TrackerGeometry";
0047   }
0048 
0049   edm::LogInfo("AlignableBuildProcess") << "@SUB=AlignableTrackerBuilder::AlignableTrackerBuilder"
0050                                         << "GeometryVersion: " << ss.str();
0051 }
0052 
0053 //_____________________________________________________________________________
0054 void AlignableTrackerBuilder ::buildAlignables(AlignableTracker* trackerAlignables, bool update) {
0055   alignableMap_ = &trackerAlignables->alignableMap_;
0056 
0057   // first, build Alignables on module-level (AlignableDetUnits)
0058   buildAlignableDetUnits(update);
0059 
0060   // now build the composite Alignables (Ladders, Layers etc.)
0061   buildAlignableComposites(update);
0062 
0063   if (update)
0064     return;  // everything else not needed for the update
0065 
0066   // create pixel-detector
0067   buildPixelDetector(trackerAlignables);
0068 
0069   // for the Outer Tracker, decide which geometry we are addressing
0070   if (alignableObjectId_.geometry() < AlignableObjectId::Geometry::PhaseII) {
0071     // create strip-detector
0072     buildStripDetector(trackerAlignables);
0073   } else {
0074     // create Phase2 Outer Tracker-detector
0075     buildOuterTrackerDetector(trackerAlignables);
0076   }
0077 
0078   // tracker itself is of course also an Alignable
0079   alignableMap_->get("Tracker").push_back(trackerAlignables);
0080   // id is the id of first component (should be TPBBarrel)
0081   trackerAlignables->theId = trackerAlignables->components()[0]->id();
0082 }
0083 
0084 //=============================================================================
0085 //===   PRIVATE METHOD IMPLEMENTATION                                       ===
0086 //=============================================================================
0087 
0088 //_____________________________________________________________________________
0089 void AlignableTrackerBuilder ::buildAlignableDetUnits(bool update) {
0090   // PixelBarrel
0091   convertGeomDetsToAlignables(trackerGeometry_->detsPXB(), alignableObjectId_.idToString(align::TPBModule), update);
0092 
0093   // PixelEndcap
0094   convertGeomDetsToAlignables(trackerGeometry_->detsPXF(), alignableObjectId_.idToString(align::TPEModule), update);
0095 
0096   // TIB
0097   convertGeomDetsToAlignables(trackerGeometry_->detsTIB(), alignableObjectId_.idToString(align::TIBModule), update);
0098 
0099   // TID
0100   convertGeomDetsToAlignables(trackerGeometry_->detsTID(), alignableObjectId_.idToString(align::TIDModule), update);
0101 
0102   // TOB
0103   convertGeomDetsToAlignables(trackerGeometry_->detsTOB(), alignableObjectId_.idToString(align::TOBModule), update);
0104 
0105   // TEC
0106   convertGeomDetsToAlignables(trackerGeometry_->detsTEC(), alignableObjectId_.idToString(align::TECModule), update);
0107 }
0108 
0109 //_____________________________________________________________________________
0110 void AlignableTrackerBuilder ::convertGeomDetsToAlignables(const TrackingGeometry::DetContainer& geomDets,
0111                                                            const std::string& moduleName,
0112                                                            bool update) {
0113   numDetUnits = 0;
0114 
0115   auto& alignables = alignableMap_->get(moduleName);
0116   if (!update)
0117     alignables.reserve(geomDets.size());
0118 
0119   // units are added for each moduleName, which are at moduleName + "Unit"
0120   // in the pixel Module and ModuleUnit are equivalent
0121   auto& aliUnits = alignableMap_->get(moduleName + "Unit");
0122   if (!update)
0123     aliUnits.reserve(geomDets.size());  // minimal number space needed
0124 
0125   for (auto& geomDet : geomDets) {
0126     int subdetId = geomDet->geographicalId().subdetId();  //don't check det()==Tracker
0127 
0128     if (subdetId == PixelSubdetector::PixelBarrel || subdetId == PixelSubdetector::PixelEndcap) {
0129       buildPixelDetectorAlignable(geomDet, subdetId, alignables, aliUnits, update);
0130 
0131     } else if (subdetId == SiStripDetId::TIB || subdetId == SiStripDetId::TID || subdetId == SiStripDetId::TOB ||
0132                subdetId == SiStripDetId::TEC) {
0133       // for strip we create also <TIB/TID/TOB/TEC>ModuleUnit list
0134       // for 1D components of 2D layers
0135 
0136       if (alignableObjectId_.geometry() < AlignableObjectId::Geometry::PhaseII) {
0137         buildStripDetectorAlignable(geomDet, subdetId, alignables, aliUnits, update);
0138       } else {
0139         buildOuterTrackerDetectorAlignable(geomDet, subdetId, alignables, aliUnits, update);
0140       }
0141 
0142     } else {
0143       throw cms::Exception("LogicError") << "[AlignableTrackerBuilder] GeomDet of unknown subdetector";
0144     }
0145 
0146     trackerAlignmentLevelBuilder_.addDetUnitInfo(geomDet->geographicalId());
0147   }
0148 
0149   // JFI: For PXB and PXE we exclusively build AlignableDetUnit, hence
0150   // alignables.size() and numDetUnits are equal. But for modules in Strip
0151   // we also create AlignableSiStripDets, which consist of multiple
0152   // AlignableDetUnits, hence alignables.size() and numDetUnits are not equal.
0153 
0154   edm::LogInfo("AlignableBuildProcess") << "@SUB=AlignableTrackerBuilder::convertGeomDetsToAlignables"
0155                                         << "converted GeomDets to Alignables for " << moduleName << "\n"
0156                                         << "   GeomDets:             " << geomDets.size() << "\n"
0157                                         << "   AlignableDetUnits:    " << numDetUnits;
0158 }
0159 
0160 //_____________________________________________________________________________
0161 void AlignableTrackerBuilder ::buildPixelDetectorAlignable(
0162     const GeomDet* geomDetUnit, int subdetId, Alignables& aliDets, Alignables& aliDetUnits, bool update) {
0163   // treat all pixel dets in same way with one AlignableDetUnit
0164   if (!geomDetUnit->isLeaf()) {
0165     throw cms::Exception("BadHierarchy") << "[AlignableTrackerBuilder] Pixel GeomDet (subdetector " << subdetId
0166                                          << ") is not a GeomDetUnit.";
0167   }
0168 
0169   if (update) {
0170     auto ali = std::find_if(aliDets.cbegin(), aliDets.cend(), [&geomDetUnit](const auto& i) {
0171       return i->id() == geomDetUnit->geographicalId().rawId();
0172     });
0173     if (ali != aliDets.end()) {
0174       // add dynamic cast here to get AlignableDetUnit!
0175       auto aliDetUnit = dynamic_cast<AlignableDetUnit*>(*ali);
0176       if (aliDetUnit) {
0177         aliDetUnit->update(geomDetUnit);
0178       } else {
0179         throw cms::Exception("LogicError") << "[AlignableTrackerBuilder::buildPixelDetectorAlignable] "
0180                                            << "cast to 'AlignableDetUnit*' failed while it should not\n";
0181       }
0182     } else {
0183       throw cms::Exception("GeometryMismatch")
0184           << "[AlignableTrackerBuilder::buildPixelDetectorAlignable] "
0185           << "GeomDet with DetId " << geomDetUnit->geographicalId().rawId() << " not found in current geometry.\n";
0186     }
0187   } else {
0188     aliDets.push_back(new AlignableDetUnit(geomDetUnit));
0189     aliDetUnits.push_back(aliDets.back());
0190   }
0191   numDetUnits += 1;
0192 }
0193 
0194 //_____________________________________________________________________________
0195 void AlignableTrackerBuilder ::buildStripDetectorAlignable(
0196     const GeomDet* geomDet, int subdetId, Alignables& aliDets, Alignables& aliDetUnits, bool update) {
0197   // In strip we have:
0198   // 1) 'Pure' 1D-modules like TOB layers 3-6 (not glued): AlignableDetUnit
0199   // 2) Composite 2D-modules like TOB layers 1&2 (not glued): AlignableDet
0200   // 3) The two 1D-components of case 2 (glued): AlignableDetUnit that is constructed
0201   //      inside AlignableDet-constructor of 'mother', only need to add to alignableLists
0202   const SiStripDetId detId(geomDet->geographicalId());
0203 
0204   // 2D- or 'pure' 1D-module
0205   if (!detId.glued()) {
0206     if (!geomDet->components().empty()) {
0207       // 2D-module, convert it to GluedGeomDet
0208       const GluedGeomDet* gluedGeomDet = dynamic_cast<const GluedGeomDet*>(geomDet);
0209       if (!gluedGeomDet) {
0210         throw cms::Exception("LogicError") << "[AlignableTrackerBuilder] dynamic_cast<const GluedGeomDet*> "
0211                                            << "failed.";
0212       }
0213 
0214       // components (AlignableDetUnits) constructed within
0215       if (update) {
0216         auto ali = std::find_if(aliDets.cbegin(), aliDets.cend(), [&gluedGeomDet](const auto& i) {
0217           return i->id() == gluedGeomDet->geographicalId().rawId();
0218         });
0219         if (ali != aliDets.end()) {
0220           auto aliSiStripDet = dynamic_cast<AlignableSiStripDet*>(*ali);
0221           if (aliSiStripDet) {
0222             aliSiStripDet->update(gluedGeomDet);
0223           } else {
0224             throw cms::Exception("LogicError") << "[AlignableTrackerBuilder::buildStripDetectorAlignable] "
0225                                                << "cast to 'AlignableSiStripDet*' failed while it should not\n";
0226           }
0227         } else {
0228           throw cms::Exception("GeometryMismatch")
0229               << "[AlignableTrackerBuilder::buildStripDetectorAlignable] "
0230               << "GeomDet with DetId " << gluedGeomDet->geographicalId().rawId() << " not found in current geometry.\n";
0231         }
0232       } else {
0233         aliDets.push_back(new AlignableSiStripDet(gluedGeomDet));
0234       }
0235       const auto& addAliDetUnits = aliDets.back()->components();
0236       const auto& nAddedUnits = addAliDetUnits.size();
0237 
0238       if (!update) {
0239         // reserve space for the additional units:
0240         aliDetUnits.reserve(aliDetUnits.size() + nAddedUnits - 1);
0241         aliDetUnits.insert(aliDetUnits.end(), addAliDetUnits.begin(), addAliDetUnits.end());
0242       }
0243       numDetUnits += nAddedUnits;
0244 
0245     } else {
0246       // no components: pure 1D-module
0247       buildPixelDetectorAlignable(geomDet, subdetId, aliDets, aliDetUnits, update);
0248     }
0249   }  // no else: glued components of AlignableDet constructed within
0250   // AlignableSiStripDet -> AlignableDet, see above
0251 }
0252 
0253 //_____________________________________________________________________________
0254 void AlignableTrackerBuilder ::buildOuterTrackerDetectorAlignable(
0255     const GeomDet* geomDet, int subdetId, Alignables& aliDets, Alignables& aliDetUnits, bool update) {
0256   // hopefully all the geomdets are composite (either PS or SS modules in Ph-2 Outer Tracker)
0257   if (!geomDet->components().empty()) {
0258     // 2D-module, convert it to StackGeomDet
0259     const StackGeomDet* stackGeomDet = dynamic_cast<const StackGeomDet*>(geomDet);
0260     if (!stackGeomDet) {
0261       throw cms::Exception("LogicError") << "[AlignableTrackerBuilder] dynamic_cast<const StackGeomDet*> "
0262                                          << "failed.";
0263     }
0264 
0265     // components (AlignableDetUnits) constructed within
0266     if (update) {
0267       auto ali = std::find_if(aliDets.cbegin(), aliDets.cend(), [&stackGeomDet](const auto& i) {
0268         return i->id() == stackGeomDet->geographicalId().rawId();
0269       });
0270       if (ali != aliDets.end()) {
0271         auto aliStackDet = dynamic_cast<AlignableStackDet*>(*ali);
0272         if (aliStackDet) {
0273           aliStackDet->update(geomDet);
0274         } else {
0275           throw cms::Exception("LogicError") << "[AlignableTrackerBuilder::buildOuterTrackerDetectorAlignable] "
0276                                              << "cast to 'AlignableStackDet*' failed while it should not\n";
0277         }
0278       } else {
0279         throw cms::Exception("GeometryMismatch")
0280             << "[AlignableTrackerBuilder::buildStripDetectorAlignable] "
0281             << "GeomDet with DetId " << stackGeomDet->geographicalId().rawId() << " not found in current geometry.\n";
0282       }
0283     } else {
0284       aliDets.push_back(new AlignableStackDet(stackGeomDet));
0285     }
0286     const auto& addAliDetUnits = aliDets.back()->components();
0287     const auto& nAddedUnits = addAliDetUnits.size();
0288 
0289     if (!update) {
0290       // reserve space for the additional units:
0291       aliDetUnits.reserve(aliDetUnits.size() + nAddedUnits - 1);
0292       aliDetUnits.insert(aliDetUnits.end(), addAliDetUnits.begin(), addAliDetUnits.end());
0293     }
0294     numDetUnits += nAddedUnits;
0295   }  // no else: stacked components of AlignableDet constructed within
0296   // AlignableStackDet -> AlignableDet, see above
0297 }
0298 
0299 //_____________________________________________________________________________
0300 void AlignableTrackerBuilder ::buildAlignableComposites(bool update) {
0301   unsigned int numCompositeAlignables = 0;
0302 
0303   // tracker levels must be built before the indexer is created in order to pass
0304   // a valid namespace to the indexer; an exception would be thrown if one tries
0305   // to get the namespace w/o building the levels
0306   auto trackerLevels = trackerAlignmentLevelBuilder_.build();
0307   TrackerAlignableIndexer trackerIndexer{trackerAlignmentLevelBuilder_.trackerNameSpace()};
0308   AlignableCompositeBuilder compositeBuilder{trackerTopology_, trackerGeometry_, trackerIndexer};
0309 
0310   for (auto& trackerSubLevels : trackerLevels) {
0311     // first add all levels of the current subdetector to the builder
0312     for (auto& level : trackerSubLevels) {
0313       compositeBuilder.addAlignmentLevel(std::move(level));
0314     }
0315     // now build this tracker-level
0316     numCompositeAlignables += compositeBuilder.buildAll(*alignableMap_, update);
0317     // finally, reset the builder
0318     compositeBuilder.clearAlignmentLevels();
0319   }
0320 
0321   edm::LogInfo("AlignableBuildProcess") << "@SUB=AlignableTrackerBuilder::buildAlignableComposites"
0322                                         << "AlignableComposites built for Tracker: " << numCompositeAlignables
0323                                         << " (note: without Pixel- and Strip-Alignable)";
0324 }
0325 
0326 //_____________________________________________________________________________
0327 void AlignableTrackerBuilder ::buildPixelDetector(AlignableTracker* trackerAlignables) {
0328   const std::string& pxbName = alignableObjectId_.idToString(align::TPBBarrel);
0329   const std::string& pxeName = alignableObjectId_.idToString(align::TPEEndcap);
0330   const std::string& pixelName = alignableObjectId_.idToString(align::Pixel);
0331 
0332   auto& pxbAlignables = alignableMap_->find(pxbName);
0333   auto& pxeAlignables = alignableMap_->find(pxeName);
0334   auto& pixelAlignables = alignableMap_->get(pixelName);
0335 
0336   pixelAlignables.push_back(new AlignableComposite(pxbAlignables[0]->id(), align::Pixel, align::RotationType()));
0337 
0338   pixelAlignables[0]->addComponent(pxbAlignables[0]);
0339   pixelAlignables[0]->addComponent(pxeAlignables[0]);
0340   pixelAlignables[0]->addComponent(pxeAlignables[1]);
0341 
0342   trackerAlignables->addComponent(pixelAlignables[0]);
0343 
0344   edm::LogInfo("AlignableBuildProcess") << "@SUB=AlignableTrackerBuilder::buildPixelDetector"
0345                                         << "Built " << pixelName << "-detector Alignable, consisting of Alignables"
0346                                         << " of " << pxbName << " and " << pxeName;
0347 }
0348 
0349 //_____________________________________________________________________________
0350 void AlignableTrackerBuilder ::buildStripDetector(AlignableTracker* trackerAlignables) {
0351   const std::string& tibName = alignableObjectId_.idToString(align::TIBBarrel);
0352   const std::string& tidName = alignableObjectId_.idToString(align::TIDEndcap);
0353   const std::string& tobName = alignableObjectId_.idToString(align::TOBBarrel);
0354   const std::string& tecName = alignableObjectId_.idToString(align::TECEndcap);
0355   const std::string& stripName = alignableObjectId_.idToString(align::Strip);
0356 
0357   auto& tibAlignables = alignableMap_->find(tibName);
0358   auto& tidAlignables = alignableMap_->find(tidName);
0359   auto& tobAlignables = alignableMap_->find(tobName);
0360   auto& tecAlignables = alignableMap_->find(tecName);
0361   auto& stripAlignables = alignableMap_->get(stripName);
0362 
0363   stripAlignables.push_back(new AlignableComposite(tibAlignables[0]->id(), align::Strip, align::RotationType()));
0364 
0365   stripAlignables[0]->addComponent(tibAlignables[0]);
0366   stripAlignables[0]->addComponent(tidAlignables[0]);
0367   stripAlignables[0]->addComponent(tidAlignables[1]);
0368   stripAlignables[0]->addComponent(tobAlignables[0]);
0369   stripAlignables[0]->addComponent(tecAlignables[0]);
0370   stripAlignables[0]->addComponent(tecAlignables[1]);
0371 
0372   trackerAlignables->addComponent(stripAlignables[0]);
0373 
0374   edm::LogInfo("AlignableBuildProcess") << "@SUB=AlignableTrackerBuilder::buildStripDetector"
0375                                         << "Built " << stripName << "-detector Alignable, consisting of Alignables"
0376                                         << " of " << tibName << ", " << tidName << ", " << tobName << " and "
0377                                         << tecName;
0378 }
0379 
0380 //_____________________________________________________________________________
0381 void AlignableTrackerBuilder ::buildOuterTrackerDetector(AlignableTracker* trackerAlignables) {
0382   const std::string& tidName = alignableObjectId_.idToString(align::TIDEndcap);
0383   const std::string& tobName = alignableObjectId_.idToString(align::TOBBarrel);
0384   const std::string& stripName = alignableObjectId_.idToString(align::Strip);
0385 
0386   auto& tidAlignables = alignableMap_->find(tidName);
0387   auto& tobAlignables = alignableMap_->find(tobName);
0388   auto& stripAlignables = alignableMap_->get(stripName);
0389 
0390   stripAlignables.push_back(new AlignableComposite(tobAlignables[0]->id(), align::Strip, align::RotationType()));
0391   stripAlignables[0]->addComponent(tobAlignables[0]);
0392   stripAlignables[0]->addComponent(tidAlignables[0]);
0393   stripAlignables[0]->addComponent(tidAlignables[1]);
0394 
0395   trackerAlignables->addComponent(stripAlignables[0]);
0396 
0397   edm::LogInfo("AlignableBuildProcess") << "@SUB=AlignableTrackerBuilder::buildStripDetector"
0398                                         << "Built " << stripName << "-detector Alignable, consisting of Alignables"
0399                                         << " of " << tidName << " and " << tobName;
0400 }