CMS 3D CMS Logo

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