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