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 // system include files
23 #include <memory>
24 #include <unordered_map>
25 
26 // user include files
35 
38 
40 
46 
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 // member functions
90 //
91 
92 // ------------ method called for each event ------------
94  if (!firstEvent_)
95  return;
96  firstEvent_ = false;
97 
98  // get handle on bad modules
99  edm::ESHandle<SiPixelQuality> pixelModules;
100  iSetup.get<SiPixelQualityRcd>().get(pixelModules);
101  edm::ESHandle<SiStripQuality> stripModules;
102  iSetup.get<SiStripQualityRcd>().get(stripModules);
103 
104  // get the tracker geometry
105  edm::ESHandle<GeometricDet> geometricDet;
106  iSetup.get<IdealGeometryRecord>().get(geometricDet);
108  iSetup.get<PTrackerParametersRcd>().get(ptp);
109  edm::ESHandle<TrackerTopology> tTopoHandle;
110  iSetup.get<TrackerTopologyRcd>().get(tTopoHandle);
111  const auto* const topology = tTopoHandle.product();
112  TrackerGeomBuilderFromGeometricDet trackerBuilder;
113  auto tracker = std::unique_ptr<TrackerGeometry>{trackerBuilder.build(&(*geometricDet), *ptp, topology)};
114 
115  auto dets = tracker->dets();
116  std::sort(dets.begin(), dets.end(), [](const auto& a, const auto& b) {
117  return a->geographicalId().rawId() < b->geographicalId().rawId();
118  });
119 
120  // get the input alignment
121  edm::ESHandle<Alignments> alignments;
122  iSetup.get<TrackerAlignmentRcd>().get(alignments);
123 
124  if (dets.size() != alignments->m_align.size()) {
125  throw cms::Exception("GeometryMismatch") << "Size mismatch between alignments (size=" << alignments->m_align.size()
126  << ") and ideal geometry (size=" << dets.size() << ")";
127  }
128 
129  Alignments rescaledAlignments{};
130  {
131  auto outlierCounter{0};
132  auto ideal = dets.cbegin();
133  const auto& ideal_end = dets.cend();
134  auto misaligned = alignments->m_align.cbegin();
135  for (; ideal != ideal_end; ++ideal, ++misaligned) {
136  if ((*ideal)->geographicalId().rawId() != misaligned->rawId()) {
137  throw cms::Exception("GeometryMismatch") << "Order differs between Dets in alignments ideal geometry.";
138  }
139 
140  // determine scale factor
141  const auto& subDetId = (*ideal)->geographicalId().subdetId();
142  auto side = topology->side((*ideal)->geographicalId());
143  if (side == 0) {
144  switch (subDetId) {
146  side = 1; // both sides are treated identical -> pick one of them
147  break;
149  side = topology->tibSide((*ideal)->geographicalId());
150  break;
152  side = topology->tobSide((*ideal)->geographicalId());
153  break;
154  default:
155  break;
156  }
157  }
158  auto scaleFactor = scalers_.find(subDetId)->second.find(side)->second;
159 
161  (pixelModules->IsModuleBad(misaligned->rawId()) || stripModules->IsModuleBad(misaligned->rawId()))) {
162  scaleFactor = 0.0;
163  }
164 
165  auto x_diff = misaligned->translation().x() - (*ideal)->position().x();
166  auto y_diff = misaligned->translation().y() - (*ideal)->position().y();
167  auto z_diff = misaligned->translation().z() - (*ideal)->position().z();
168 
169  auto xx_diff = misaligned->rotation().xx() - (*ideal)->rotation().xx();
170  auto xy_diff = misaligned->rotation().xy() - (*ideal)->rotation().xy();
171  auto xz_diff = misaligned->rotation().xz() - (*ideal)->rotation().xz();
172  auto yx_diff = misaligned->rotation().yx() - (*ideal)->rotation().yx();
173  auto yy_diff = misaligned->rotation().yy() - (*ideal)->rotation().yy();
174  auto yz_diff = misaligned->rotation().yz() - (*ideal)->rotation().yz();
175  auto zx_diff = misaligned->rotation().zx() - (*ideal)->rotation().zx();
176  auto zy_diff = misaligned->rotation().zy() - (*ideal)->rotation().zy();
177  auto zz_diff = misaligned->rotation().zz() - (*ideal)->rotation().zz();
178 
179  if (outlierPullToIdealCut_ > 0.0 &&
180  (x_diff * x_diff + y_diff * y_diff + z_diff * z_diff) > outlierPullToIdealCut_ * outlierPullToIdealCut_) {
181  ++outlierCounter;
182  edm::LogInfo("Alignment") << outlierCounter << ") Outlier found in subdetector " << subDetId
183  << ": delta x: " << x_diff << ", delta y: " << y_diff << ", delta z: " << z_diff
184  << ", delta xx: " << xx_diff << ", delta xy: " << xy_diff
185  << ", delta xz: " << xz_diff << ", delta yx: " << yx_diff
186  << ", delta yx: " << yy_diff << ", delta yy: " << yz_diff
187  << ", delta zz: " << zx_diff << ", delta zy: " << zy_diff
188  << ", delta zz: " << zz_diff << "\n";
189  scaleFactor = 0.0;
190  }
191 
192  const AlignTransform::Translation rescaledTranslation{(*ideal)->position().x() + scaleFactor * x_diff,
193  (*ideal)->position().y() + scaleFactor * y_diff,
194  (*ideal)->position().z() + scaleFactor * z_diff};
195 
196  const AlignTransform::Rotation rescaledRotation{
197  CLHEP::HepRep3x3{(*ideal)->rotation().xx() + scaleFactor * xx_diff,
198  (*ideal)->rotation().xy() + scaleFactor * xy_diff,
199  (*ideal)->rotation().xz() + scaleFactor * xz_diff,
200  (*ideal)->rotation().yx() + scaleFactor * yx_diff,
201  (*ideal)->rotation().yy() + scaleFactor * yy_diff,
202  (*ideal)->rotation().yz() + scaleFactor * yz_diff,
203  (*ideal)->rotation().zx() + scaleFactor * zx_diff,
204  (*ideal)->rotation().zy() + scaleFactor * zy_diff,
205  (*ideal)->rotation().zz() + scaleFactor * zz_diff}};
206 
207  const AlignTransform rescaledTransform{rescaledTranslation, rescaledRotation, misaligned->rawId()};
208  rescaledAlignments.m_align.emplace_back(std::move(rescaledTransform));
209  }
210  }
211 
213  if (!poolDb.isAvailable()) {
214  throw cms::Exception("NotAvailable") << "PoolDBOutputService not available";
215  }
216  edm::LogInfo("Alignment") << "Writing rescaled tracker-alignment record.";
218  poolDb->writeOne(&rescaledAlignments, since, "TrackerAlignmentRcd");
219 }
220 
222  // initialize scaler map
223  ScalerMap subDetMap;
224  for (unsigned int subDetId = 1; subDetId <= 6; ++subDetId) {
225  subDetMap[subDetId][1] = 1.0;
226  subDetMap[subDetId][2] = 1.0;
227  }
228 
229  // apply scale factors from configuration
230  for (const auto& pset : psets) {
231  const auto& name = pset.getUntrackedParameter<std::string>("subDetector");
232  const auto& factor = pset.getUntrackedParameter<double>("factor");
233 
234  std::vector<int> sides;
235  if (name.find("-") != std::string::npos)
236  sides.push_back(1);
237  if (name.find("+") != std::string::npos)
238  sides.push_back(2);
239  if (sides.empty()) { // -> use both sides
240  sides.push_back(1);
241  sides.push_back(2);
242  }
243 
244  if (name.find("Tracker") != std::string::npos) {
245  for (unsigned int subDetId = 1; subDetId <= 6; ++subDetId) {
246  for (const auto& side : sides)
247  subDetMap[subDetId][side] *= factor;
248  }
249  if (sides.size() == 1) {
250  // if only one side to be scaled
251  // -> scale also the other side for PXB (subdetid = 1)
252  subDetMap[PixelSubdetector::PixelBarrel][std::abs(sides[0] - 2) + 1] *= factor;
253  }
254  } else if (name.find("PXB") != std::string::npos) {
255  // ignore sides for PXB
256  subDetMap[PixelSubdetector::PixelBarrel][1] *= factor;
257  subDetMap[PixelSubdetector::PixelBarrel][2] *= factor;
258  } else if (name.find("PXF") != std::string::npos) {
259  for (const auto& side : sides)
260  subDetMap[PixelSubdetector::PixelEndcap][side] *= factor;
261  } else if (name.find("TIB") != std::string::npos) {
262  for (const auto& side : sides)
263  subDetMap[StripSubdetector::TIB][side] *= factor;
264  } else if (name.find("TOB") != std::string::npos) {
265  for (const auto& side : sides)
266  subDetMap[StripSubdetector::TOB][side] *= factor;
267  } else if (name.find("TID") != std::string::npos) {
268  for (const auto& side : sides)
269  subDetMap[StripSubdetector::TID][side] *= factor;
270  } else if (name.find("TEC") != std::string::npos) {
271  for (const auto& side : sides)
272  subDetMap[StripSubdetector::TEC][side] *= factor;
273  } else {
274  throw cms::Exception("BadConfig") << "@SUB=MCMisalignmentScaler::decodeSubDetectors\n"
275  << "Unknown tracker subdetector: " << name
276  << "\nSupported options: Tracker, PXB, PXF, TIB, TOB, TID, TEC "
277  << "(possibly decorated with '+' or '-')";
278  }
279  }
280 
281  std::stringstream logInfo;
282  logInfo << "MC misalignment scale factors:\n";
283  for (const auto& subdet : subDetMap) {
284  logInfo << " Subdet " << subdet.first << "\n";
285  for (const auto& side : subdet.second) {
286  logInfo << " side " << side.first << ": " << side.second << "\n";
287  }
288  logInfo << "\n";
289  }
290  edm::LogInfo("Alignment") << logInfo.str();
291 
292  return subDetMap;
293 }
294 
295 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
298  desc.setComment(
299  "Creates rescaled MC misalignment scenario. "
300  "PoolDBOutputService must be set up for 'TrackerAlignmentRcd'.");
301  edm::ParameterSetDescription descScaler;
302  descScaler.setComment(
303  "ParameterSet specifying the tracker part to be scaled "
304  "by a given factor.");
305  descScaler.addUntracked<std::string>("subDetector", "Tracker");
306  descScaler.addUntracked<double>("factor", 1.0);
307  desc.addVPSet("scalers", descScaler, std::vector<edm::ParameterSet>(1));
308  desc.addUntracked<bool>("pullBadModulesToIdeal", false);
309  desc.addUntracked<double>("outlierPullToIdealCut", -1.0);
310  descriptions.add("mcMisalignmentScaler", desc);
311 }
312 
313 //define this as a plug-in
const TimeTypeSpecs timeTypeSpecs[]
Definition: Time.cc:16
T getParameter(std::string const &) const
static constexpr auto TEC
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:41
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)
static constexpr auto TOB
void analyze(const edm::Event &, const edm::EventSetup &) override
bool IsModuleBad(const uint32_t &detid) const
static constexpr auto TIB
double b
Definition: hdecay.h:118
void add(std::string const &label, ParameterSetDescription const &psetDescription)
double a
Definition: hdecay.h:119
T get() const
Definition: EventSetup.h:73
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
T const * product() const
Definition: ESHandle.h:86
def move(src, dest)
Definition: eostools.py:511
CLHEP::HepRotation Rotation