Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include <memory>
0002 
0003 // Framework
0004 #include "FWCore/Utilities/interface/Exception.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 
0007 #include "CondFormats/Alignment/interface/Alignments.h"
0008 #include "CondFormats/Alignment/interface/AlignmentErrorsExtended.h"
0009 #include "DataFormats/GeometryCommonDetAlgo/interface/AlignmentPositionError.h"
0010 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0011 
0012 #include "Alignment/CommonAlignment/interface/AlignableComposite.h"
0013 
0014 //__________________________________________________________________________________________________
0015 AlignableComposite::AlignableComposite(const GeomDet* geomDet)
0016     : Alignable(geomDet->geographicalId().rawId(), geomDet->surface()), theStructureType(align::AlignableDet) {
0017   compConstraintType_ = Alignable::CompConstraintType::POSITION;
0018 }
0019 
0020 //__________________________________________________________________________________________________
0021 AlignableComposite::AlignableComposite(align::ID id, StructureType type, const RotationType& rot)
0022     : Alignable(id, rot), theStructureType(type) {
0023   compConstraintType_ = Alignable::CompConstraintType::POSITION;
0024 }
0025 
0026 //__________________________________________________________________________________________________
0027 AlignableComposite::~AlignableComposite() {
0028   for (unsigned int i = 0; i < theComponents.size(); ++i)
0029     delete theComponents[i];
0030 }
0031 
0032 //__________________________________________________________________________________________________
0033 void AlignableComposite::update(const GeomDet* geomDet) {
0034   if (!geomDet) {
0035     throw cms::Exception("Alignment") << "@SUB=AlignableComposite::update\n"
0036                                       << "Trying to update with GeomDet* pointing to 'nullptr'.";
0037   }
0038 
0039   Alignable::update(geomDet->geographicalId().rawId(), geomDet->surface());
0040 }
0041 
0042 //__________________________________________________________________________________________________
0043 void AlignableComposite::update(align::ID id, StructureType type, const RotationType& rot) {
0044   if (theStructureType != type) {
0045     throw cms::Exception("Alignment") << "@SUB=AlignableComposite::update\n"
0046                                       << "Current alignable type does not match type of the update.";
0047   }
0048   // composite's position is already updated by components, i.e. it needs to be kept
0049   Alignable::update(id, AlignableSurface{this->globalPosition(), rot});
0050 }
0051 
0052 //__________________________________________________________________________________________________
0053 void AlignableComposite::addComponent(Alignable* ali) {
0054   const auto& newComps = ali->deepComponents();
0055 
0056   theDeepComponents.insert(theDeepComponents.end(), newComps.begin(), newComps.end());
0057 
0058   Scalar k = static_cast<Scalar>(newComps.size()) / theDeepComponents.size();
0059 
0060   theSurface.move((ali->globalPosition() - globalPosition()) * k);
0061 
0062   ali->setMother(this);
0063   theComponents.push_back(ali);
0064 }
0065 
0066 //__________________________________________________________________________________________________
0067 void AlignableComposite::recursiveComponents(Alignables& result) const {
0068   const auto& components = this->components();
0069   if (this->alignableObjectId() == align::AlignableDet &&
0070       components.size() <= 1) {  // Non-glued AlignableDets (still) contain themselves
0071     return;                      // (would be better to implement AlignableDet::recursiveComponents!)
0072   }
0073   for (const auto& iter : components) {
0074     result.push_back(iter);  // could use std::copy(..), but here we build a real hierarchy
0075     iter->recursiveComponents(result);
0076   }
0077 }
0078 
0079 //__________________________________________________________________________________________________
0080 void AlignableComposite::move(const GlobalVector& displacement) {
0081   // Move components
0082   for (const auto& i : this->components())
0083     i->move(displacement);
0084 
0085   // Move surface
0086   this->addDisplacement(displacement);
0087   theSurface.move(displacement);
0088 }
0089 
0090 //__________________________________________________________________________________________________
0091 void AlignableComposite::moveComponentsLocal(const LocalVector& localDisplacement) {
0092   this->move(this->surface().toGlobal(localDisplacement));
0093 }
0094 
0095 //__________________________________________________________________________________________________
0096 void AlignableComposite::moveComponentLocal(const int i, const LocalVector& localDisplacement) {
0097   if (i >= size())
0098     throw cms::Exception("LogicError") << "AlignableComposite index (" << i << ") out of range";
0099 
0100   const auto& comp = this->components();
0101   comp[i]->move(this->surface().toGlobal(localDisplacement));
0102 }
0103 
0104 //__________________________________________________________________________________________________
0105 /// Rotation intepreted such, that the orientation of the rotation
0106 /// axis is w.r.t. to the global coordinate system. This, however, does NOT
0107 /// mean the center of the rotation. This is simply taken as the center of
0108 /// the Alignable-object
0109 void AlignableComposite::rotateInGlobalFrame(const RotationType& rotation) {
0110   const auto& comp = this->components();
0111 
0112   PositionType myPosition = this->globalPosition();
0113 
0114   for (const auto& i : comp) {
0115     // It is much simpler to calculate the local position given in coordinates
0116     // of the GLOBAL frame and then just apply the rotation matrix given in the
0117     // GLOBAL frame as well. ONLY this is somewhat tricky... as Teddy's frames
0118     // don't like this kind of mixing...
0119 
0120     // Rotations are defined for "Basic3DVector" types, without any FrameTAG,
0121     // because Rotations usually switch between different frames. You get
0122     // this by using the method .basicVector()
0123 
0124     // localPosition = globalPosition (Component) - globalPosition(Composite)
0125     // moveVector = rotated localPosition  - original localposition
0126     // LocalVector localPositionVector = (**i).globalPosition()-myPosition;
0127 
0128     // Local Position given in coordinates of the GLOBAL Frame
0129     const GlobalVector localPositionVector = i->globalPosition() - myPosition;
0130     const GlobalVector::BasicVectorType& lpvgf = localPositionVector.basicVector();
0131 
0132     // rotate with GLOBAL rotation matrix  and subtract => moveVector in
0133     // global Coordinates
0134     // apparently... you have to use the inverse of the rotation here
0135     // (rotate the VECTOR rather than the frame)
0136     GlobalVector moveVector(rotation.multiplyInverse(lpvgf) - lpvgf);
0137 
0138     i->move(moveVector);
0139     i->rotateInGlobalFrame(rotation);
0140   }
0141 
0142   this->addRotation(rotation);
0143 
0144   theSurface.rotate(rotation);
0145 }
0146 
0147 //__________________________________________________________________________________________________
0148 void AlignableComposite::setAlignmentPositionError(const AlignmentPositionError& ape, bool propagateDown) {
0149   // Since no geomDet is attached, alignable composites do not have an APE
0150   // The APE is, therefore, just propagated down
0151   if (!propagateDown)
0152     return;
0153 
0154   for (const auto& i : this->components()) {
0155     i->setAlignmentPositionError(ape, propagateDown);
0156   }
0157 }
0158 
0159 //__________________________________________________________________________________________________
0160 void AlignableComposite::addAlignmentPositionError(const AlignmentPositionError& ape, bool propagateDown) {
0161   // Since no geomDet is attached, alignable composites do not have an APE
0162   // The APE is, therefore, just propagated down
0163   if (!propagateDown)
0164     return;
0165 
0166   for (const auto& i : this->components()) {
0167     i->addAlignmentPositionError(ape, propagateDown);
0168   }
0169 }
0170 
0171 //__________________________________________________________________________________________________
0172 /// Adds the AlignmentPositionError (in x,y,z coordinates) that would result
0173 /// on the various components from a possible Rotation of a composite the
0174 /// rotation matrix is in interpreted in GLOBAL coordinates
0175 void AlignableComposite::addAlignmentPositionErrorFromRotation(const RotationType& rotation, bool propagateDown) {
0176   if (!propagateDown)
0177     return;
0178 
0179   PositionType myPosition = this->globalPosition();
0180 
0181   for (const auto& i : this->components()) {
0182     // It is just similar to to the "movement" that results to the components
0183     // when the composite is rotated.
0184     // Local Position given in coordinates of the GLOBAL Frame
0185     const GlobalVector localPositionVector = i->globalPosition() - myPosition;
0186     const GlobalVector::BasicVectorType& lpvgf = localPositionVector.basicVector();
0187 
0188     // rotate with GLOBAL rotation matrix  and subtract => moveVector in global coordinates
0189     // apparently... you have to use the inverse of the rotation here
0190     // (rotate the VECTOR rather than the frame)
0191     GlobalVector moveVector(rotation.multiplyInverse(lpvgf) - lpvgf);
0192 
0193     AlignmentPositionError ape(moveVector.x(), moveVector.y(), moveVector.z());
0194     i->addAlignmentPositionError(ape, propagateDown);
0195     i->addAlignmentPositionErrorFromRotation(rotation, propagateDown);
0196   }
0197 }
0198 
0199 //__________________________________________________________________________________________________
0200 /// Adds the AlignmentPositionError (in x,y,z coordinates) that would result
0201 /// on the various components from a possible Rotation of a composite the
0202 /// rotation matrix is in interpreted in LOCAL  coordinates of the composite
0203 void AlignableComposite::addAlignmentPositionErrorFromLocalRotation(const RotationType& rot, bool propagateDown) {
0204   // if (!propagateDown) return; // No! Cannot yet jump out since
0205   // addAlignmentPositionErrorFromRotation(..) below might be overwritten in derived
0206   // classes to do something on 'this' (and in fact does so in AlignableDet).
0207 
0208   RotationType globalRot = globalRotation().multiplyInverse(rot * globalRotation());
0209   this->addAlignmentPositionErrorFromRotation(globalRot, propagateDown);
0210 }
0211 
0212 //__________________________________________________________________________________________________
0213 void AlignableComposite::setSurfaceDeformation(const SurfaceDeformation* deformation, bool propagateDown) {
0214   // Only DetUnits have surface deformations.
0215   // The parameters are, therefore, just propagated down.
0216   if (!propagateDown)
0217     return;
0218 
0219   for (const auto& i : this->components()) {
0220     i->setSurfaceDeformation(deformation, propagateDown);
0221   }
0222 }
0223 
0224 //__________________________________________________________________________________________________
0225 void AlignableComposite::addSurfaceDeformation(const SurfaceDeformation* deformation, bool propagateDown) {
0226   // Only DetUnits have surface deformations.
0227   // The parameters are, therefore, just propagated down.
0228   if (!propagateDown)
0229     return;
0230 
0231   for (const auto& i : this->components()) {
0232     i->addSurfaceDeformation(deformation, propagateDown);
0233   }
0234 }
0235 
0236 //__________________________________________________________________________________________________
0237 void AlignableComposite::dump(void) const {
0238   // A simple printout method. Could be specialized in the implementation classes.
0239 
0240   const auto& comp = this->components();
0241 
0242   // Dump this
0243   edm::LogInfo("AlignableDump") << " Alignable of type " << this->alignableObjectId() << " has " << comp.size()
0244                                 << " components" << std::endl
0245                                 << " position = " << this->globalPosition() << ", orientation:" << std::endl
0246                                 << this->globalRotation();
0247 
0248   // Dump components
0249   for (const auto& i : comp)
0250     i->dump();
0251 }
0252 
0253 //__________________________________________________________________________________________________
0254 Alignments* AlignableComposite::alignments(void) const {
0255   // Recursively call alignments, until we get to an AlignableDetUnit
0256 
0257   Alignments* m_alignments = new Alignments();
0258 
0259   // Add components recursively
0260   for (const auto& i : this->components()) {
0261     std::unique_ptr<Alignments> tmpAlignments{i->alignments()};
0262     std::copy(tmpAlignments->m_align.begin(), tmpAlignments->m_align.end(), std::back_inserter(m_alignments->m_align));
0263   }
0264 
0265   return m_alignments;
0266 }
0267 
0268 //__________________________________________________________________________________________________
0269 AlignmentErrorsExtended* AlignableComposite::alignmentErrors(void) const {
0270   // Recursively call alignmentsErrors, until we get to an AlignableDetUnit
0271 
0272   AlignmentErrorsExtended* m_alignmentErrors = new AlignmentErrorsExtended();
0273 
0274   // Add components recursively
0275   for (const auto& i : this->components()) {
0276     std::unique_ptr<AlignmentErrorsExtended> tmpAlignmentErrorsExtended{i->alignmentErrors()};
0277     std::copy(tmpAlignmentErrorsExtended->m_alignError.begin(),
0278               tmpAlignmentErrorsExtended->m_alignError.end(),
0279               std::back_inserter(m_alignmentErrors->m_alignError));
0280   }
0281 
0282   return m_alignmentErrors;
0283 }
0284 
0285 //__________________________________________________________________________________________________
0286 int AlignableComposite::surfaceDeformationIdPairs(std::vector<std::pair<int, SurfaceDeformation*> >& result) const {
0287   int count = 0;
0288 
0289   // Add components recursively
0290   for (const auto& i : this->components()) {
0291     count += i->surfaceDeformationIdPairs(result);
0292   }
0293 
0294   return count;
0295 }