CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MCMisalignmentScaler.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Alignment/TrackerAlignment
4 // Class: MCMisalignmentScaler
5 //
16 //
17 // Original Author: Gregor Mittag
18 // Created: Tue, 10 Oct 2017 15:49:17 GMT
19 //
20 //
21 
22 // system include files
23 #include <memory>
24 #include <unordered_map>
25 
26 // user include files
35 
38 
40 
47 
50 
57 
58 //
59 // class declaration
60 //
61 
63 public:
64  explicit MCMisalignmentScaler(const edm::ParameterSet&);
65  ~MCMisalignmentScaler() override = default;
66 
68 
69 private:
77  using ScalerMap = std::unordered_map<unsigned int, std::unordered_map<int, double> >;
78 
79  void analyze(const edm::Event&, const edm::EventSetup&) override;
81 
82  // ----------member data ---------------------------
85  const double outlierPullToIdealCut_;
86  bool firstEvent_{true};
87 };
88 
89 //
90 // constructors and destructor
91 //
94  stripQualityToken_(esConsumes()),
95  geomDetToken_(esConsumes()),
96  ptpToken_(esConsumes()),
97  ptitpToken_(esConsumes()),
98  topoToken_(esConsumes()),
99  aliToken_(esConsumes()),
100  scalers_{decodeSubDetectors(iConfig.getParameter<edm::VParameterSet>("scalers"))},
101  pullBadModulesToIdeal_{iConfig.getUntrackedParameter<bool>("pullBadModulesToIdeal")},
102  outlierPullToIdealCut_{iConfig.getUntrackedParameter<double>("outlierPullToIdealCut")} {}
103 
104 //
105 // member functions
106 //
107 
108 // ------------ method called for each event ------------
110  if (!firstEvent_)
111  return;
112  firstEvent_ = false;
113 
114  // get handle on bad modules
115  const SiPixelQuality* pixelModules = &iSetup.getData(pixelQualityToken_);
116  const SiStripQuality* stripModules = &iSetup.getData(stripQualityToken_);
117 
118  // get the tracker geometry
119  const GeometricDet* geometricDet = &iSetup.getData(geomDetToken_);
120  const PTrackerParameters& ptp = iSetup.getData(ptpToken_);
122  const TrackerTopology* topology = &iSetup.getData(topoToken_);
123 
124  TrackerGeomBuilderFromGeometricDet trackerBuilder;
125  auto tracker = std::unique_ptr<TrackerGeometry>{trackerBuilder.build(geometricDet, ptitp, ptp, topology)};
126 
127  auto dets = tracker->dets();
128  std::sort(dets.begin(), dets.end(), [](const auto& a, const auto& b) {
129  return a->geographicalId().rawId() < b->geographicalId().rawId();
130  });
131 
132  // get the input alignment
133  const Alignments* alignments = &iSetup.getData(aliToken_);
134 
135  if (dets.size() != alignments->m_align.size()) {
136  throw cms::Exception("GeometryMismatch") << "Size mismatch between alignments (size=" << alignments->m_align.size()
137  << ") and ideal geometry (size=" << dets.size() << ")";
138  }
139 
140  Alignments rescaledAlignments{};
141  {
142  auto outlierCounter{0};
143  auto ideal = dets.cbegin();
144  const auto& ideal_end = dets.cend();
145  auto misaligned = alignments->m_align.cbegin();
146  for (; ideal != ideal_end; ++ideal, ++misaligned) {
147  if ((*ideal)->geographicalId().rawId() != misaligned->rawId()) {
148  throw cms::Exception("GeometryMismatch") << "Order differs between Dets in alignments ideal geometry.";
149  }
150 
151  // determine scale factor
152  const auto& subDetId = (*ideal)->geographicalId().subdetId();
153  auto side = topology->side((*ideal)->geographicalId());
154  if (side == 0) {
155  switch (subDetId) {
157  side = 1; // both sides are treated identical -> pick one of them
158  break;
160  side = topology->tibSide((*ideal)->geographicalId());
161  break;
163  side = topology->tobSide((*ideal)->geographicalId());
164  break;
165  default:
166  break;
167  }
168  }
169  auto scaleFactor = scalers_.find(subDetId)->second.find(side)->second;
170 
172  (pixelModules->IsModuleBad(misaligned->rawId()) || stripModules->IsModuleBad(misaligned->rawId()))) {
173  scaleFactor = 0.0;
174  }
175 
176  auto x_diff = misaligned->translation().x() - (*ideal)->position().x();
177  auto y_diff = misaligned->translation().y() - (*ideal)->position().y();
178  auto z_diff = misaligned->translation().z() - (*ideal)->position().z();
179 
180  auto xx_diff = misaligned->rotation().xx() - (*ideal)->rotation().xx();
181  auto xy_diff = misaligned->rotation().xy() - (*ideal)->rotation().xy();
182  auto xz_diff = misaligned->rotation().xz() - (*ideal)->rotation().xz();
183  auto yx_diff = misaligned->rotation().yx() - (*ideal)->rotation().yx();
184  auto yy_diff = misaligned->rotation().yy() - (*ideal)->rotation().yy();
185  auto yz_diff = misaligned->rotation().yz() - (*ideal)->rotation().yz();
186  auto zx_diff = misaligned->rotation().zx() - (*ideal)->rotation().zx();
187  auto zy_diff = misaligned->rotation().zy() - (*ideal)->rotation().zy();
188  auto zz_diff = misaligned->rotation().zz() - (*ideal)->rotation().zz();
189 
190  if (outlierPullToIdealCut_ > 0.0 &&
191  (x_diff * x_diff + y_diff * y_diff + z_diff * z_diff) > outlierPullToIdealCut_ * outlierPullToIdealCut_) {
192  ++outlierCounter;
193  edm::LogInfo("Alignment") << outlierCounter << ") Outlier found in subdetector " << subDetId
194  << ": delta x: " << x_diff << ", delta y: " << y_diff << ", delta z: " << z_diff
195  << ", delta xx: " << xx_diff << ", delta xy: " << xy_diff
196  << ", delta xz: " << xz_diff << ", delta yx: " << yx_diff
197  << ", delta yx: " << yy_diff << ", delta yy: " << yz_diff
198  << ", delta zz: " << zx_diff << ", delta zy: " << zy_diff
199  << ", delta zz: " << zz_diff << "\n";
200  scaleFactor = 0.0;
201  }
202 
203  const AlignTransform::Translation rescaledTranslation{(*ideal)->position().x() + scaleFactor * x_diff,
204  (*ideal)->position().y() + scaleFactor * y_diff,
205  (*ideal)->position().z() + scaleFactor * z_diff};
206 
207  const AlignTransform::Rotation rescaledRotation{
208  CLHEP::HepRep3x3{(*ideal)->rotation().xx() + scaleFactor * xx_diff,
209  (*ideal)->rotation().xy() + scaleFactor * xy_diff,
210  (*ideal)->rotation().xz() + scaleFactor * xz_diff,
211  (*ideal)->rotation().yx() + scaleFactor * yx_diff,
212  (*ideal)->rotation().yy() + scaleFactor * yy_diff,
213  (*ideal)->rotation().yz() + scaleFactor * yz_diff,
214  (*ideal)->rotation().zx() + scaleFactor * zx_diff,
215  (*ideal)->rotation().zy() + scaleFactor * zy_diff,
216  (*ideal)->rotation().zz() + scaleFactor * zz_diff}};
217 
218  const AlignTransform rescaledTransform{rescaledTranslation, rescaledRotation, misaligned->rawId()};
219  rescaledAlignments.m_align.emplace_back(rescaledTransform);
220  }
221  }
222 
224  if (!poolDb.isAvailable()) {
225  throw cms::Exception("NotAvailable") << "PoolDBOutputService not available";
226  }
227  edm::LogInfo("Alignment") << "Writing rescaled tracker-alignment record.";
229  poolDb->writeOneIOV(rescaledAlignments, since, "TrackerAlignmentRcd");
230 }
231 
233  // initialize scaler map
234  ScalerMap subDetMap;
235  for (unsigned int subDetId = 1; subDetId <= 6; ++subDetId) {
236  subDetMap[subDetId][1] = 1.0;
237  subDetMap[subDetId][2] = 1.0;
238  }
239 
240  // apply scale factors from configuration
241  for (const auto& pset : psets) {
242  const auto& name = pset.getUntrackedParameter<std::string>("subDetector");
243  const auto& factor = pset.getUntrackedParameter<double>("factor");
244 
245  std::vector<int> sides;
246  if (name.find('-') != std::string::npos)
247  sides.push_back(1);
248  if (name.find('+') != std::string::npos)
249  sides.push_back(2);
250  if (sides.empty()) { // -> use both sides
251  sides.push_back(1);
252  sides.push_back(2);
253  }
254 
255  if (name.find("Tracker") != std::string::npos) {
256  for (unsigned int subDetId = 1; subDetId <= 6; ++subDetId) {
257  for (const auto& side : sides)
258  subDetMap[subDetId][side] *= factor;
259  }
260  if (sides.size() == 1) {
261  // if only one side to be scaled
262  // -> scale also the other side for PXB (subdetid = 1)
263  subDetMap[PixelSubdetector::PixelBarrel][std::abs(sides[0] - 2) + 1] *= factor;
264  }
265  } else if (name.find("PXB") != std::string::npos) {
266  // ignore sides for PXB
267  subDetMap[PixelSubdetector::PixelBarrel][1] *= factor;
268  subDetMap[PixelSubdetector::PixelBarrel][2] *= factor;
269  } else if (name.find("PXF") != std::string::npos) {
270  for (const auto& side : sides)
271  subDetMap[PixelSubdetector::PixelEndcap][side] *= factor;
272  } else if (name.find("TIB") != std::string::npos) {
273  for (const auto& side : sides)
274  subDetMap[StripSubdetector::TIB][side] *= factor;
275  } else if (name.find("TOB") != std::string::npos) {
276  for (const auto& side : sides)
277  subDetMap[StripSubdetector::TOB][side] *= factor;
278  } else if (name.find("TID") != std::string::npos) {
279  for (const auto& side : sides)
280  subDetMap[StripSubdetector::TID][side] *= factor;
281  } else if (name.find("TEC") != std::string::npos) {
282  for (const auto& side : sides)
283  subDetMap[StripSubdetector::TEC][side] *= factor;
284  } else {
285  throw cms::Exception("BadConfig") << "@SUB=MCMisalignmentScaler::decodeSubDetectors\n"
286  << "Unknown tracker subdetector: " << name
287  << "\nSupported options: Tracker, PXB, PXF, TIB, TOB, TID, TEC "
288  << "(possibly decorated with '+' or '-')";
289  }
290  }
291 
292  std::stringstream logInfo;
293  logInfo << "MC misalignment scale factors:\n";
294  for (const auto& subdet : subDetMap) {
295  logInfo << " Subdet " << subdet.first << "\n";
296  for (const auto& side : subdet.second) {
297  logInfo << " side " << side.first << ": " << side.second << "\n";
298  }
299  logInfo << "\n";
300  }
301  edm::LogInfo("Alignment") << logInfo.str();
302 
303  return subDetMap;
304 }
305 
306 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
309  desc.setComment(
310  "Creates rescaled MC misalignment scenario. "
311  "PoolDBOutputService must be set up for 'TrackerAlignmentRcd'.");
312  edm::ParameterSetDescription descScaler;
313  descScaler.setComment(
314  "ParameterSet specifying the tracker part to be scaled "
315  "by a given factor.");
316  descScaler.addUntracked<std::string>("subDetector", "Tracker");
317  descScaler.addUntracked<double>("factor", 1.0);
318  desc.addVPSet("scalers", descScaler, std::vector<edm::ParameterSet>(1));
319  desc.addUntracked<bool>("pullBadModulesToIdeal", false);
320  desc.addUntracked<double>("outlierPullToIdealCut", -1.0);
321  descriptions.add("mcMisalignmentScaler", desc);
322 }
323 
324 //define this as a plug-in
const edm::ESGetToken< PTrackerAdditionalParametersPerDet, PTrackerAdditionalParametersPerDetRcd > ptitpToken_
const TimeTypeSpecs timeTypeSpecs[]
Definition: Time.cc:16
static constexpr auto TEC
const edm::ESGetToken< Alignments, TrackerAlignmentRcd > aliToken_
ParameterDescriptionBase * addVPSet(U const &iLabel, ParameterSetDescription const &validator, std::vector< ParameterSet > const &defaults)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
Time_t beginValue
Definition: Time.h:41
const edm::ESGetToken< SiPixelQuality, SiPixelQualityRcd > pixelQualityToken_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::vector< ParameterSet > VParameterSet
Definition: ParameterSet.h:34
TrackerGeometry * build(const GeometricDet *gd, const PTrackerAdditionalParametersPerDet *ptitp, const PTrackerParameters &ptp, const TrackerTopology *tTopo)
constexpr unsigned int subDetId[21]
CLHEP::Hep3Vector Translation
unsigned int side(const DetId &id) const
const DetContainer & dets() const override
Returm a vector of all GeomDet (including all GeomDetUnits)
std::vector< AlignTransform > m_align
Definition: Alignments.h:19
const edm::ESGetToken< GeometricDet, IdealGeometryRecord > geomDetToken_
const double outlierPullToIdealCut_
bool getData(T &iHolder) const
Definition: EventSetup.h:122
void setComment(std::string const &value)
unsigned int tibSide(const DetId &id) const
MCMisalignmentScaler(const edm::ParameterSet &)
std::unordered_map< unsigned int, std::unordered_map< int, double > > ScalerMap
~MCMisalignmentScaler() override=default
ScalerMap decodeSubDetectors(const edm::VParameterSet &)
unsigned int tobSide(const DetId &id) const
bool isAvailable() const
Definition: Service.h:40
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Hash writeOneIOV(const T &payload, Time_t time, const std::string &recordName)
static constexpr auto TOB
void analyze(const edm::Event &, const edm::EventSetup &) override
bool IsModuleBad(const uint32_t &detid) const
Log< level::Info, false > LogInfo
pixelQualityToken_(iC.esConsumes())
static constexpr auto TIB
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
bool IsModuleBad(uint32_t detid) const
double b
Definition: hdecay.h:118
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const edm::ESGetToken< SiStripQuality, SiStripQualityRcd > stripQualityToken_
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > topoToken_
double a
Definition: hdecay.h:119
static void fillDescriptions(edm::ConfigurationDescriptions &)
align::ID rawId() const
Do not expose Euler angles since we may change its type later.
static constexpr auto TID
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
const edm::ESGetToken< PTrackerParameters, PTrackerParametersRcd > ptpToken_
CLHEP::HepRotation Rotation