Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
#include "Alignment/CommonAlignment/interface/AlignableDetUnit.h"
#include "CondFormats/Alignment/interface/Alignments.h"
#include "CondFormats/Alignment/interface/AlignmentErrorsExtended.h"
#include "CLHEP/Vector/RotationInterfaces.h"
#include "DataFormats/GeometryCommonDetAlgo/interface/AlignmentPositionError.h"
#include "Geometry/CommonDetUnit/interface/GeomDet.h"

#include "Alignment/CommonAlignment/interface/AlignableDet.h"

#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"

//__________________________________________________________________________________________________
AlignableDet::AlignableDet(const GeomDet* geomDet, bool addComponents)
    : AlignableComposite(geomDet), theAlignmentPositionError(nullptr) {
  // ensure that the surface is not constrained to the average position of the
  // components:
  compConstraintType_ = Alignable::CompConstraintType::NONE;

  if (geomDet->alignmentPositionError()) {
    // false: do not propagate APE to (anyway not yet existing) daughters
    this->setAlignmentPositionError(*(geomDet->alignmentPositionError()), false);
  }

  if (addComponents) {
    if (geomDet->components().empty()) {  // Is a DetUnit
      throw cms::Exception("BadHierarchy") << "[AlignableDet] GeomDet with DetId " << geomDet->geographicalId().rawId()
                                           << " has no components, use AlignableDetUnit.\n";
    } else {  // Push back all components
      const std::vector<const GeomDet*>& geomDets = geomDet->components();
      for (std::vector<const GeomDet*>::const_iterator idet = geomDets.begin(); idet != geomDets.end(); ++idet) {
        const GeomDetUnit* unit = dynamic_cast<const GeomDetUnit*>(*idet);
        if (!unit) {
          throw cms::Exception("BadHierarchy")
              << "[AlignableDet] component not GeomDetUnit, call with addComponents==false"
              << " and build hierarchy yourself.\n";  // e.g. AlignableDTChamber
        }
        this->addComponent(new AlignableDetUnit(unit));
      }
    }
    // Ensure that the surface is not screwed up by addComponent, it must stay the GeomDet's one:
    theSurface = AlignableSurface(geomDet->surface());
  }  // end addComponents
}

//__________________________________________________________________________________________________
AlignableDet::~AlignableDet() { delete theAlignmentPositionError; }

//______________________________________________________________________________
void AlignableDet::update(const GeomDet* geomDet, bool updateComponents) {
  AlignableComposite::update(geomDet);

  if (geomDet->alignmentPositionError()) {
    // false: do not propagate APE to daughters (done by their update functions)
    this->setAlignmentPositionError(*(geomDet->alignmentPositionError()), false);
  }

  if (updateComponents) {
    if (geomDet->components().empty()) {  // Is a DetUnit
      throw cms::Exception("BadHierarchy") << "[AlignableDet] GeomDet with DetId " << geomDet->geographicalId().rawId()
                                           << " has no components, use AlignableDetUnit.\n";
    } else {  // Push back all components
      const auto& geomDets = geomDet->components();
      for (const auto& idet : geomDets) {
        auto unit = dynamic_cast<const GeomDetUnit*>(idet);
        if (!unit) {
          throw cms::Exception("BadHierarchy") << "[AlignableDet] component not GeomDetUnit, call with "
                                               << "updateComponents==false and build hierarchy yourself.\n";
          // -> e.g. AlignableDTChamber
        }

        const auto components = this->components();
        auto comp = std::find_if(components.begin(), components.end(), [&unit](const auto& c) {
          return c->id() == unit->geographicalId().rawId();
        });

        if (comp != components.end()) {
          auto aliDetUnit = dynamic_cast<AlignableDetUnit*>(*comp);
          if (aliDetUnit) {
            aliDetUnit->update(unit);
          } else {
            throw cms::Exception("LogicError") << "[AlignableDet::update] cast to 'AlignableDetUnit*' failed "
                                               << "while it should not\n";
          }
        } else {
          throw cms::Exception("GeometryMismatch")
              << "[AlignableDet::update] GeomDet with DetId " << unit->geographicalId().rawId()
              << " not found in current geometry.\n";
        }
      }
    }
    // Ensure that the surface is not screwed up by update of components, it must stay the GeomDet's one:
    theSurface = AlignableSurface(geomDet->surface());
  }  // end updateComponents
}

//__________________________________________________________________________________________________
void AlignableDet::setAlignmentPositionError(const AlignmentPositionError& ape, bool propagateDown) {
  if (!theAlignmentPositionError)
    theAlignmentPositionError = new AlignmentPositionError(ape);
  else
    *theAlignmentPositionError = ape;

  this->AlignableComposite::setAlignmentPositionError(ape, propagateDown);
}

//__________________________________________________________________________________________________
void AlignableDet::addAlignmentPositionError(const AlignmentPositionError& ape, bool propagateDown) {
  if (!theAlignmentPositionError) {
    theAlignmentPositionError = new AlignmentPositionError(ape);
  } else {
    *theAlignmentPositionError += ape;
  }

  this->AlignableComposite::addAlignmentPositionError(ape, propagateDown);
}

//__________________________________________________________________________________________________
void AlignableDet::addAlignmentPositionErrorFromRotation(const RotationType& rot, bool propagateDown) {
  // average error calculated by movement of a local point at
  // (xWidth/2,yLength/2,0) caused by the rotation rot
  GlobalVector localPositionVector =
      surface().toGlobal(LocalVector(.5 * surface().width(), .5 * surface().length(), 0.));

  const LocalVector::BasicVectorType& lpvgf = localPositionVector.basicVector();
  GlobalVector gv(rot.multiplyInverse(lpvgf) - lpvgf);

  AlignmentPositionError ape(gv.x(), gv.y(), gv.z());
  this->addAlignmentPositionError(ape, propagateDown);

  this->AlignableComposite::addAlignmentPositionErrorFromRotation(rot, propagateDown);
}

//__________________________________________________________________________________________________
Alignments* AlignableDet::alignments() const {
  Alignments* m_alignments = new Alignments();
  RotationType rot(this->globalRotation());

  // Get position, rotation, detId
  CLHEP::Hep3Vector clhepVector(globalPosition().x(), globalPosition().y(), globalPosition().z());
  CLHEP::HepRotation clhepRotation(
      CLHEP::HepRep3x3(rot.xx(), rot.xy(), rot.xz(), rot.yx(), rot.yy(), rot.yz(), rot.zx(), rot.zy(), rot.zz()));
  uint32_t detId = this->geomDetId().rawId();

  AlignTransform transform(clhepVector, clhepRotation, detId);

  // Add to alignments container
  m_alignments->m_align.push_back(transform);

  // Add those from components
  Alignments* compAlignments = this->AlignableComposite::alignments();
  std::copy(compAlignments->m_align.begin(), compAlignments->m_align.end(), std::back_inserter(m_alignments->m_align));
  delete compAlignments;

  return m_alignments;
}

//__________________________________________________________________________________________________
AlignmentErrorsExtended* AlignableDet::alignmentErrors(void) const {
  AlignmentErrorsExtended* m_alignmentErrors = new AlignmentErrorsExtended();

  // Add associated alignment position error
  uint32_t detId = this->geomDetId().rawId();
  CLHEP::HepSymMatrix clhepSymMatrix(6, 0);
  if (theAlignmentPositionError)  // Might not be set
    clhepSymMatrix = asHepMatrix(theAlignmentPositionError->globalError().matrix());
  AlignTransformErrorExtended transformError(clhepSymMatrix, detId);
  m_alignmentErrors->m_alignError.push_back(transformError);

  // Add those from components
  AlignmentErrorsExtended* compAlignmentErrs = this->AlignableComposite::alignmentErrors();
  std::copy(compAlignmentErrs->m_alignError.begin(),
            compAlignmentErrs->m_alignError.end(),
            std::back_inserter(m_alignmentErrors->m_alignError));
  delete compAlignmentErrs;

  return m_alignmentErrors;
}