Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:06

0001 #include "Alignment/CommonAlignment/interface/AlignableCompositeBuilder.h"
0002 
0003 // Original Author:  Max Stark
0004 //         Created:  Thu, 13 Jan 2016 10:22:57 CET
0005 
0006 // core framework functionality
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 
0009 // alignment
0010 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
0011 
0012 //=============================================================================
0013 //===   PUBLIC METHOD IMPLEMENTATION                                        ===
0014 //=============================================================================
0015 
0016 //_____________________________________________________________________________
0017 AlignableCompositeBuilder ::AlignableCompositeBuilder(const TrackerTopology* trackerTopology,
0018                                                       const TrackerGeometry* trackerGeometry,
0019                                                       const AlignableIndexer& alignableIndexer)
0020     : trackerTopology_(trackerTopology),
0021       alignableObjectId_(trackerGeometry, nullptr, nullptr, nullptr),
0022       alignableIndexer_(alignableIndexer) {}
0023 
0024 //_____________________________________________________________________________
0025 void AlignableCompositeBuilder ::addAlignmentLevel(std::unique_ptr<AlignmentLevel> level) {
0026   alignmentLevels_.push_back(std::move(level));
0027 }
0028 
0029 //_____________________________________________________________________________
0030 void AlignableCompositeBuilder ::clearAlignmentLevels() { alignmentLevels_.clear(); }
0031 
0032 //_____________________________________________________________________________
0033 unsigned int AlignableCompositeBuilder ::buildAll(AlignableMap& alignableMap, bool update) {
0034   auto highestLevel = alignmentLevels_.back()->levelType;
0035 
0036   std::ostringstream ss;
0037   ss << "building CompositeAlignables for " << alignableObjectId_.idToString(highestLevel) << "\n";
0038 
0039   unsigned int numCompositeAlignables = 0;
0040   for (unsigned int level = 1; level < alignmentLevels_.size(); ++level) {
0041     numCompositeAlignables += buildLevel(level, alignableMap, ss, update);
0042   }
0043 
0044   ss << "built " << numCompositeAlignables << " CompositeAlignables for "
0045      << alignableObjectId_.idToString(highestLevel);
0046   edm::LogInfo("AlignableBuildProcess") << "@SUB=AlignableCompositeBuilder::buildAll" << ss.str();
0047 
0048   return numCompositeAlignables;
0049 }
0050 
0051 //=============================================================================
0052 //===   PRIVATE METHOD IMPLEMENTATION                                       ===
0053 //=============================================================================
0054 
0055 //_____________________________________________________________________________
0056 unsigned int AlignableCompositeBuilder ::buildLevel(unsigned int parentLevel,
0057                                                     AlignableMap& alignableMap,
0058                                                     std::ostringstream& ss,
0059                                                     bool update) {
0060   unsigned int childLevel = parentLevel - 1;
0061   unsigned int maxNumParents = maxNumComponents(parentLevel);
0062 
0063   auto childType = alignmentLevels_[childLevel]->levelType;
0064   auto parentType = alignmentLevels_[parentLevel]->levelType;
0065 
0066   auto& children = alignableMap.find(alignableObjectId_.idToString(childType));
0067   auto& parents = alignableMap.get(alignableObjectId_.idToString(parentType));
0068   if (!update)
0069     parents.reserve(maxNumParents);
0070 
0071   // This vector is used indicate if a parent already exists. It is initialized
0072   // with 'naked' Alignables-pointers; if the pointer is not naked (!= nullptr)
0073   // for one of the child-IDs, its parent was already built before.
0074   align::Alignables tmpParents(maxNumParents, nullptr);
0075 
0076   for (auto* child : children) {
0077     // get the number of the child-Alignable ...
0078     const auto index = getIndexOfStructure(child->id(), parentLevel);
0079     // ... and use it as index to get the parent of this child
0080     auto& parent = tmpParents[index];
0081 
0082     // if parent was not built yet ...
0083     if (!parent && !update) {
0084       if (update) {
0085         throw cms::Exception("LogicError") << "@SUB=AlignableCompositeBuilder::buildLevel\n"
0086                                            << "trying to update a non-existing AlignableComposite";
0087       }
0088       // ... build new composite Alignable with ID of child (obviously its the
0089       // first child of the Alignable)
0090       if (alignmentLevels_[parentLevel]->isFlat) {
0091         parent = new AlignableComposite(child->id(), parentType, child->globalRotation());
0092       } else {
0093         parent = new AlignableComposite(child->id(), parentType, align::RotationType());
0094       }
0095       parents.push_back(parent);
0096     } else if (update) {
0097       if (alignmentLevels_[parentLevel]->isFlat) {
0098         // needed to update rotation of flat composites
0099         auto mother = dynamic_cast<AlignableComposite*>(child->mother());
0100         if (!mother) {
0101           throw cms::Exception("LogicError") << "@SUB=AlignableCompositeBuilder::buildLevel\n"
0102                                              << "trying to update a flat composite that is not of type "
0103                                              << "AlignableComposite";
0104         }
0105         if (mother->id() == child->id()) {
0106           mother->update(child->id(), parentType, child->globalRotation());
0107         }
0108       }
0109     }
0110 
0111     // in all cases (except updates) add the child to the parent Alignable
0112     if (!update)
0113       parent->addComponent(child);
0114   }
0115 
0116   ss << "   built " << parents.size() << " " << alignableObjectId_.idToString(alignmentLevels_[parentLevel]->levelType)
0117      << "(s) (theoretical maximum: " << maxNumParents << ") consisting of " << children.size() << " "
0118      << alignableObjectId_.idToString(alignmentLevels_[childLevel]->levelType) << "(s)\n";
0119 
0120   return parents.size();
0121 }
0122 
0123 //_____________________________________________________________________________
0124 unsigned int AlignableCompositeBuilder ::maxNumComponents(unsigned int startLevel) const {
0125   unsigned int components = 1;
0126 
0127   for (unsigned int level = startLevel; level < alignmentLevels_.size(); ++level) {
0128     components *= alignmentLevels_[level]->maxNumComponents;
0129   }
0130 
0131   return components;
0132 }
0133 
0134 //_____________________________________________________________________________
0135 unsigned int AlignableCompositeBuilder ::getIndexOfStructure(align::ID id, unsigned int level) const {
0136   // indexer returns a function pointer for the structure-type
0137   auto indexOf = alignableIndexer_.get(alignmentLevels_[level]->levelType, alignableObjectId_);
0138 
0139   if (alignmentLevels_.size() - 1 > level) {
0140     return getIndexOfStructure(id, level + 1) * alignmentLevels_[level]->maxNumComponents + indexOf(id) - 1;
0141   }
0142 
0143   return indexOf(id) - 1;
0144 }