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 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
//  \file AlignableNavigator.cc
//
//   $Revision: 1.22 $
//   $Date: 2010/09/10 10:30:03 $
//   (last update by $Author: mussgill $)

#include "Alignment/CommonAlignment/interface/AlignableDet.h"
#include "Alignment/CommonAlignment/interface/AlignableDetUnit.h"
#include "Alignment/CommonAlignment/interface/AlignableExtras.h"
#include "Alignment/CommonAlignment/interface/AlignableBeamSpot.h"
#include "DataFormats/DetId/interface/DetId.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/Utilities/interface/Exception.h"

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

//_____________________________________________________________________________
AlignableNavigator::AlignableNavigator(Alignable* tracker, Alignable* muon) {
  theMap.clear();

  const unsigned int numNonDets = this->recursiveGetId(tracker) + this->recursiveGetId(muon);

  if (numNonDets) {
    edm::LogWarning("Alignment") << "@SUB=AlignableNavigator"
                                 << "Created with map of size " << theMap.size() << ", but found also " << numNonDets
                                 << " Alignables that have DetId!=0,\nbeing neither "
                                 << "AlignableDet nor AlignableDetUnit. This will "
                                 << "lead to an exception in case alignableFromDetId(..) "
                                 << "is called for one of these DetIds.\n"
                                 << "If there is no exception, you can ignore this message.";
  } else {
    edm::LogInfo("Alignment") << "@SUB=AlignableNavigator"
                              << "Created with map of size " << theMap.size() << ".";
  }
}

//_____________________________________________________________________________
AlignableNavigator::AlignableNavigator(AlignableExtras* extras, Alignable* tracker, Alignable* muon) {
  theMap.clear();

  unsigned int numNonDets = this->recursiveGetId(tracker) + this->recursiveGetId(muon);

  if (extras) {
    for (const auto& it : extras->components()) {
      numNonDets += this->recursiveGetId(it);
    }
  }

  if (numNonDets) {
    edm::LogWarning("Alignment") << "@SUB=AlignableNavigator"
                                 << "Created with map of size " << theMap.size() << ", but found also " << numNonDets
                                 << " Alignables that have DetId!=0,\nbeing neither "
                                 << "AlignableDet nor AlignableDetUnit. This will "
                                 << "lead to an exception in case alignableFromDetId(..) "
                                 << "is called for one of these DetIds.\n"
                                 << "If there is no exception, you can ignore this message.";
  } else {
    edm::LogInfo("Alignment") << "@SUB=AlignableNavigator"
                              << "Created with map of size " << theMap.size() << ".";
  }
}

//_____________________________________________________________________________
AlignableNavigator::AlignableNavigator(const align::Alignables& alignables) {
  theMap.clear();

  unsigned int numNonDets = 0;
  for (const auto& it : alignables) {
    numNonDets += this->recursiveGetId(it);
  }
  if (numNonDets) {
    edm::LogWarning("Alignment") << "@SUB=AlignableNavigator"
                                 << "Created with map of size " << theMap.size() << ", but found also " << numNonDets
                                 << " Alignables that have DetId!=0,\nbeing neither "
                                 << "AlignableDet nor AlignableDetUnit. This will "
                                 << "lead to an exception in case alignableFromDetId(..) "
                                 << "is called for one of these DetIds.\n"
                                 << "If there is no exception, you can ignore this message.";
  } else {
    edm::LogInfo("Alignment") << "@SUB=AlignableNavigator"
                              << "created with map of size " << theMap.size() << ".";
  }
}

//_____________________________________________________________________________
AlignableDetOrUnitPtr AlignableNavigator::alignableFromGeomDet(const GeomDet* geomDet) {
  return alignableFromDetId(geomDet->geographicalId());
}

//_____________________________________________________________________________
AlignableDetOrUnitPtr AlignableNavigator::alignableFromDetId(const DetId& detid) {
  MapType::iterator position = theMap.find(detid);
  if (position != theMap.end()) {
    return position->second;
  }

  throw cms::Exception("BadLogic") << "[AlignableNavigator::alignableDetFromDetId] DetId " << detid.rawId()
                                   << " not found";

  return static_cast<AlignableDet*>(nullptr);
}

//_____________________________________________________________________________
unsigned int AlignableNavigator::recursiveGetId(Alignable* alignable) {
  // Recursive method to get the detIds of an alignable and its childs
  // and add them to the map.
  // Returns number of Alignables with DetId which are neither AlignableDet
  // nor AlignableDetUnit and are thus not added to the map.

  if (!alignable)
    return 0;

  unsigned int nProblem = 0;
  const DetId detId(alignable->geomDetId());
  if (detId.rawId()) {
    AlignableDet* aliDet;
    AlignableDetUnit* aliDetUnit;
    AlignableBeamSpot* aliBeamSpot;

    if ((aliDet = dynamic_cast<AlignableDet*>(alignable))) {
      theMap.insert(PairType(detId, aliDet));

    } else if ((aliDetUnit = dynamic_cast<AlignableDetUnit*>(alignable))) {
      theMap.insert(PairType(detId, aliDetUnit));

    } else if ((aliBeamSpot = dynamic_cast<AlignableBeamSpot*>(alignable))) {
      theMap.insert(PairType(detId, aliBeamSpot));

    } else {
      nProblem = 1;  // equivalent to '++nProblem;' which could confuse to be ina loop...
      // Cannot be an exception since it happens (illegaly) in Muon DT hierarchy:
      //         throw cms::Exception("BadLogic")
      //           << "[AlignableNavigator::recursiveGetId] Alignable with DetId " << detId.rawId()
      //           << " neither AlignableDet nor AlignableDetUnit";
    }

    if (!nProblem && !this->detAndSubdetInMap(detId)) {
      theDetAndSubdet.push_back(std::pair<int, int>(detId.det(), detId.subdetId()));
    }
  }
  const auto& comp = alignable->components();
  if (alignable->alignableObjectId() != align::AlignableDet ||
      comp.size() > 1) {  // Non-glued AlignableDets contain themselves
    for (const auto& it : comp) {
      nProblem += this->recursiveGetId(it);
    }
  }
  return nProblem;
}

//_____________________________________________________________________________
std::vector<AlignableDetOrUnitPtr> AlignableNavigator::alignablesFromHits(
    const std::vector<const TransientTrackingRecHit*>& hitvec) {
  std::vector<AlignableDetOrUnitPtr> result;
  result.reserve(hitvec.size());

  for (std::vector<const TransientTrackingRecHit*>::const_iterator ih = hitvec.begin(), iEnd = hitvec.end(); ih != iEnd;
       ++ih) {
    result.push_back(this->alignableFromDetId((*ih)->geographicalId()));
  }

  return result;
}

//_____________________________________________________________________________
std::vector<AlignableDetOrUnitPtr> AlignableNavigator::alignablesFromHits(
    const TransientTrackingRecHit::ConstRecHitContainer& hitVec) {
  std::vector<AlignableDetOrUnitPtr> result;
  result.reserve(hitVec.size());

  for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator it = hitVec.begin(), iEnd = hitVec.end();
       it != iEnd;
       ++it) {
    result.push_back(this->alignableFromDetId((*it)->geographicalId()));
  }

  return result;
}

//_____________________________________________________________________________
std::vector<AlignableDetOrUnitPtr> AlignableNavigator::alignableDetOrUnits() {
  std::vector<AlignableDetOrUnitPtr> result;
  result.reserve(theMap.size());

  for (MapType::const_iterator iIdAli = theMap.begin(); iIdAli != theMap.end(); ++iIdAli) {
    result.push_back(iIdAli->second);
  }

  return result;
}

//_____________________________________________________________________________
bool AlignableNavigator::detAndSubdetInMap(const DetId& detid) const {
  int det = detid.det();
  int subdet = detid.subdetId();
  for (std::vector<std::pair<int, int> >::const_iterator i = theDetAndSubdet.begin(); i != theDetAndSubdet.end(); ++i) {
    if (det == i->first && subdet == i->second)
      return true;
  }
  return false;
}