Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:40:46

0001 // -*- C++ -*-
0002 //
0003 // Package:    Alignment/TrackerAlignment
0004 // Class:      CreateIdealTkAlRecords
0005 //
0006 /**\class CreateIdealTkAlRecords CreateIdealTkAlRecords.cc Alignment/TrackerAlignment/plugins/CreateIdealTkAlRecords.cc
0007 
0008  Description: Plugin to create ideal tracker alignment records.
0009 
0010  Implementation:
0011      The plugin takes the geometry stored in the global tag and transfers this
0012      information to the format needed in the TrackerAlignmentRcd. The APEs are
0013      set to zero for all det IDs of the tracker geometry and put into an
0014      TrackerAlignmentErrorExtendedRcd. In addition an empty
0015      TrackerSurfaceDeformationRcd is created corresponding to ideal surfaces.
0016 
0017      An option exists to align to the content of the used global tag. This is
0018      useful, if the geometry record and the tracker alignment records do not
0019      match.
0020 
0021 */
0022 //
0023 // Original Author:  Gregor Mittag
0024 //         Created:  Tue, 26 Apr 2016 09:45:13 GMT
0025 //
0026 //
0027 
0028 // system include files
0029 #include <memory>
0030 #include <iostream>
0031 
0032 // user include files
0033 #include "FWCore/Framework/interface/Frameworkfwd.h"
0034 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0035 #include "FWCore/Framework/interface/Event.h"
0036 #include "FWCore/Framework/interface/EventSetup.h"
0037 #include "FWCore/Framework/interface/ESHandle.h"
0038 #include "FWCore/Framework/interface/MakerMacros.h"
0039 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0040 #include "FWCore/ServiceRegistry/interface/Service.h"
0041 
0042 #include "CondCore/DBOutputService/interface/PoolDBOutputService.h"
0043 
0044 #include "CondFormats/Alignment/interface/Alignments.h"
0045 #include "CondFormats/Alignment/interface/AlignTransform.h"
0046 #include "CondFormats/Alignment/interface/AlignmentErrorsExtended.h"
0047 #include "CondFormats/Alignment/interface/AlignTransformError.h"
0048 #include "CondFormats/Alignment/interface/AlignTransformErrorExtended.h"
0049 #include "CondFormats/Alignment/interface/AlignmentSurfaceDeformations.h"
0050 #include "CondFormats/AlignmentRecord/interface/TrackerAlignmentRcd.h"
0051 #include "CondFormats/AlignmentRecord/interface/TrackerAlignmentErrorExtendedRcd.h"
0052 #include "CondFormats/AlignmentRecord/interface/TrackerSurfaceDeformationRcd.h"
0053 #include "CondFormats/GeometryObjects/interface/PTrackerParameters.h"
0054 
0055 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0056 
0057 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0058 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeomBuilderFromGeometricDet.h"
0059 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0060 #include "Geometry/Records/interface/TrackerTopologyRcd.h"
0061 #include "Geometry/Records/interface/PTrackerParametersRcd.h"
0062 
0063 #include "CLHEP/Vector/RotationInterfaces.h"
0064 
0065 //
0066 // class declaration
0067 //
0068 
0069 class CreateIdealTkAlRecords : public edm::one::EDAnalyzer<> {
0070 public:
0071   explicit CreateIdealTkAlRecords(const edm::ParameterSet&);
0072   ~CreateIdealTkAlRecords() override;
0073 
0074   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0075   static std::string toString(const GeomDetEnumerators::SubDetector&);
0076   static GeomDetEnumerators::SubDetector toSubDetector(const std::string& sub);
0077   static std::vector<GeomDetEnumerators::SubDetector> toSubDetectors(const std::vector<std::string>& subs);
0078 
0079 private:
0080   void analyze(const edm::Event&, const edm::EventSetup&) override;
0081   void clearAlignmentInfos();
0082   std::unique_ptr<TrackerGeometry> retrieveGeometry(const edm::EventSetup&);
0083   void addAlignmentInfo(const GeomDet&);
0084   void alignToGT(const edm::EventSetup&);
0085   void writeToDB();
0086 
0087   // ----------member data ---------------------------
0088 
0089   const edm::ESGetToken<GeometricDet, IdealGeometryRecord> geomDetToken_;
0090   const edm::ESGetToken<PTrackerParameters, PTrackerParametersRcd> ptpToken_;
0091   const edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> topoToken_;
0092   const edm::ESGetToken<Alignments, TrackerAlignmentRcd> aliToken_;
0093   const edm::ESGetToken<AlignmentErrorsExtended, TrackerAlignmentErrorExtendedRcd> aliErrorToken_;
0094   const edm::ESGetToken<AlignmentSurfaceDeformations, TrackerSurfaceDeformationRcd> aliSurfaceToken_;
0095   const std::vector<GeomDetEnumerators::SubDetector> skipSubDetectors_;
0096   const bool alignToGlobalTag_;
0097   const bool createReferenceRcd_;
0098   bool firstEvent_;
0099   Alignments alignments_;
0100   AlignmentErrorsExtended alignmentErrors_;
0101   AlignmentSurfaceDeformations alignmentSurfaceDeformations_;
0102   std::vector<uint32_t> rawIDs_;
0103   std::vector<GeomDetEnumerators::SubDetector> subDets_;
0104 };
0105 
0106 //
0107 // constructors and destructor
0108 //
0109 CreateIdealTkAlRecords::CreateIdealTkAlRecords(const edm::ParameterSet& iConfig)
0110     : geomDetToken_(esConsumes()),
0111       ptpToken_(esConsumes()),
0112       topoToken_(esConsumes()),
0113       aliToken_(esConsumes()),
0114       aliErrorToken_(esConsumes()),
0115       aliSurfaceToken_(esConsumes()),
0116       skipSubDetectors_(toSubDetectors(iConfig.getUntrackedParameter<std::vector<std::string> >("skipSubDetectors"))),
0117       alignToGlobalTag_(iConfig.getUntrackedParameter<bool>("alignToGlobalTag")),
0118       createReferenceRcd_(iConfig.getUntrackedParameter<bool>("createReferenceRcd")),
0119       firstEvent_(true) {}
0120 
0121 CreateIdealTkAlRecords::~CreateIdealTkAlRecords() {}
0122 
0123 //
0124 // member functions
0125 //
0126 
0127 // ------------ method called for each event  ------------
0128 void CreateIdealTkAlRecords::analyze(const edm::Event&, const edm::EventSetup& iSetup) {
0129   if (firstEvent_) {
0130     clearAlignmentInfos();
0131     const auto tracker = retrieveGeometry(iSetup);
0132 
0133     auto dets = tracker->dets();
0134     std::sort(dets.begin(), dets.end(), [](const auto& a, const auto& b) {
0135       return a->geographicalId().rawId() < b->geographicalId().rawId();
0136     });
0137 
0138     for (const auto& det : dets)
0139       addAlignmentInfo(*det);
0140     if (alignToGlobalTag_ && !createReferenceRcd_)
0141       alignToGT(iSetup);
0142     writeToDB();
0143     firstEvent_ = false;
0144   }
0145 }
0146 
0147 std::string CreateIdealTkAlRecords::toString(const GeomDetEnumerators::SubDetector& sub) {
0148   switch (sub) {
0149     case GeomDetEnumerators::PixelBarrel:
0150       return "PixelBarrel";
0151     case GeomDetEnumerators::PixelEndcap:
0152       return "PixelEndcap";
0153     case GeomDetEnumerators::TIB:
0154       return "TIB";
0155     case GeomDetEnumerators::TOB:
0156       return "TOB";
0157     case GeomDetEnumerators::TID:
0158       return "TID";
0159     case GeomDetEnumerators::TEC:
0160       return "TEC";
0161     case GeomDetEnumerators::CSC:
0162       return "CSC";
0163     case GeomDetEnumerators::DT:
0164       return "DT";
0165     case GeomDetEnumerators::RPCBarrel:
0166       return "RPCBarrel";
0167     case GeomDetEnumerators::RPCEndcap:
0168       return "RPCEndcap";
0169     case GeomDetEnumerators::GEM:
0170       return "GEM";
0171     case GeomDetEnumerators::ME0:
0172       return "ME0";
0173     case GeomDetEnumerators::P2OTB:
0174       return "P2OTB";
0175     case GeomDetEnumerators::P2OTEC:
0176       return "P2OTEC";
0177     case GeomDetEnumerators::P1PXB:
0178       return "P1PXB";
0179     case GeomDetEnumerators::P1PXEC:
0180       return "P1PXEC";
0181     case GeomDetEnumerators::P2PXB:
0182       return "P2PXB";
0183     case GeomDetEnumerators::P2PXEC:
0184       return "P2PXEC";
0185     case GeomDetEnumerators::invalidDet:
0186       return "invalidDet";
0187     default:
0188       throw cms::Exception("UnknownSubdetector");
0189   }
0190 }
0191 
0192 GeomDetEnumerators::SubDetector CreateIdealTkAlRecords::toSubDetector(const std::string& sub) {
0193   if (sub == "PixelBarrel")
0194     return GeomDetEnumerators::PixelBarrel;
0195   else if (sub == "PixelEndcap")
0196     return GeomDetEnumerators::PixelEndcap;
0197   else if (sub == "TIB")
0198     return GeomDetEnumerators::TIB;
0199   else if (sub == "TOB")
0200     return GeomDetEnumerators::TOB;
0201   else if (sub == "TID")
0202     return GeomDetEnumerators::TID;
0203   else if (sub == "TEC")
0204     return GeomDetEnumerators::TEC;
0205   else if (sub == "CSC")
0206     return GeomDetEnumerators::CSC;
0207   else if (sub == "DT")
0208     return GeomDetEnumerators::DT;
0209   else if (sub == "RPCBarrel")
0210     return GeomDetEnumerators::RPCBarrel;
0211   else if (sub == "RPCEndcap")
0212     return GeomDetEnumerators::RPCEndcap;
0213   else if (sub == "GEM")
0214     return GeomDetEnumerators::GEM;
0215   else if (sub == "ME0")
0216     return GeomDetEnumerators::ME0;
0217   else if (sub == "P2OTB")
0218     return GeomDetEnumerators::P2OTB;
0219   else if (sub == "P2OTEC")
0220     return GeomDetEnumerators::P2OTEC;
0221   else if (sub == "P1PXB")
0222     return GeomDetEnumerators::P1PXB;
0223   else if (sub == "P1PXEC")
0224     return GeomDetEnumerators::P1PXEC;
0225   else if (sub == "P2PXB")
0226     return GeomDetEnumerators::P2PXB;
0227   else if (sub == "P2PXEC")
0228     return GeomDetEnumerators::P2PXEC;
0229   else if (sub == "invalidDet")
0230     return GeomDetEnumerators::invalidDet;
0231   else
0232     throw cms::Exception("UnknownSubdetector") << sub;
0233 }
0234 
0235 std::vector<GeomDetEnumerators::SubDetector> CreateIdealTkAlRecords::toSubDetectors(
0236     const std::vector<std::string>& subs) {
0237   std::vector<GeomDetEnumerators::SubDetector> result;
0238   result.reserve(subs.size());
0239   for (const auto& sub : subs)
0240     result.emplace_back(toSubDetector(sub));
0241   return result;
0242 }
0243 
0244 void CreateIdealTkAlRecords::clearAlignmentInfos() {
0245   alignments_.clear();
0246   alignmentErrors_.clear();
0247   alignmentSurfaceDeformations_ = AlignmentSurfaceDeformations{};
0248   rawIDs_.clear();
0249 }
0250 
0251 std::unique_ptr<TrackerGeometry> CreateIdealTkAlRecords::retrieveGeometry(const edm::EventSetup& iSetup) {
0252   const GeometricDet* geometricDet = &iSetup.getData(geomDetToken_);
0253   const PTrackerParameters& ptp = iSetup.getData(ptpToken_);
0254   const TrackerTopology* tTopo = &iSetup.getData(topoToken_);
0255 
0256   TrackerGeomBuilderFromGeometricDet trackerBuilder;
0257 
0258   return std::unique_ptr<TrackerGeometry>{trackerBuilder.build(geometricDet, ptp, tTopo)};
0259 }
0260 
0261 void CreateIdealTkAlRecords::addAlignmentInfo(const GeomDet& det) {
0262   const auto subDetector = toString(det.subDetector());
0263   const auto& detId = det.geographicalId().rawId();
0264   const auto& pos = det.position();
0265   const auto& rot = det.rotation();
0266   rawIDs_.push_back(detId);
0267   subDets_.push_back(det.subDetector());
0268 
0269   // TrackerAlignmentRcd entry
0270   if (createReferenceRcd_) {
0271     alignments_.m_align.emplace_back(AlignTransform(AlignTransform::Translation(), AlignTransform::Rotation(), detId));
0272   } else {
0273     const AlignTransform::Translation translation(pos.x(), pos.y(), pos.z());
0274     const AlignTransform::Rotation rotation(
0275         CLHEP::HepRep3x3(rot.xx(), rot.xy(), rot.xz(), rot.yx(), rot.yy(), rot.yz(), rot.zx(), rot.zy(), rot.zz()));
0276     const auto& eulerAngles = rotation.eulerAngles();
0277     LogDebug("Alignment") << "============================================================\n"
0278                           << "subdetector: " << subDetector << "\n"
0279                           << "detId:       " << detId << "\n"
0280                           << "------------------------------------------------------------\n"
0281                           << "     x: " << pos.x() << "\n"
0282                           << "     y: " << pos.y() << "\n"
0283                           << "     z: " << pos.z() << "\n"
0284                           << "   phi: " << eulerAngles.phi() << "\n"
0285                           << " theta: " << eulerAngles.theta() << "\n"
0286                           << "   psi: " << eulerAngles.psi() << "\n"
0287                           << "============================================================\n";
0288     alignments_.m_align.emplace_back(AlignTransform(translation, rotation, detId));
0289   }
0290 
0291   // TrackerAlignmentErrorExtendedRcd entry
0292   const AlignTransformError::SymMatrix zeroAPEs(6, 0);
0293   alignmentErrors_.m_alignError.emplace_back(AlignTransformErrorExtended(zeroAPEs, detId));
0294 }
0295 
0296 void CreateIdealTkAlRecords::alignToGT(const edm::EventSetup& iSetup) {
0297   LogDebug("Alignment") << "Aligning to global tag\n";
0298 
0299   const Alignments* alignments = &iSetup.getData(aliToken_);
0300   const AlignmentErrorsExtended* alignmentErrors = &iSetup.getData(aliErrorToken_);
0301   const AlignmentSurfaceDeformations* surfaceDeformations = &iSetup.getData(aliSurfaceToken_);
0302 
0303   if (alignments->m_align.size() != alignmentErrors->m_alignError.size())
0304     throw cms::Exception("GeometryMismatch")
0305         << "Size mismatch between alignments (size=" << alignments->m_align.size()
0306         << ") and alignment errors (size=" << alignmentErrors->m_alignError.size() << ")";
0307 
0308   std::vector<uint32_t> commonIDs;
0309   auto itAlignErr = alignmentErrors->m_alignError.cbegin();
0310   for (auto itAlign = alignments->m_align.cbegin(); itAlign != alignments->m_align.cend(); ++itAlign, ++itAlignErr) {
0311     const auto id = itAlign->rawId();
0312     auto found = std::find(rawIDs_.cbegin(), rawIDs_.cend(), id);
0313     if (found != rawIDs_.cend()) {
0314       if (id != itAlignErr->rawId())
0315         throw cms::Exception("GeometryMismatch") << "DetId mismatch between alignments (rawId=" << id
0316                                                  << ") and alignment errors (rawId=" << itAlignErr->rawId() << ")";
0317 
0318       const auto index = std::distance(rawIDs_.cbegin(), found);
0319       if (std::find(skipSubDetectors_.begin(), skipSubDetectors_.end(), subDets_[index]) != skipSubDetectors_.end())
0320         continue;
0321 
0322       if (alignments_.m_align[index].rawId() != alignmentErrors_.m_alignError[index].rawId())
0323         throw cms::Exception("GeometryMismatch")
0324             << "DetId mismatch between alignments (rawId=" << alignments_.m_align[index].rawId()
0325             << ") and alignment errors (rawId=" << alignmentErrors_.m_alignError[index].rawId() << ")";
0326 
0327       LogDebug("Alignment") << "============================================================\n"
0328                             << "\nGeometry content (" << toString(subDets_[index]) << ", "
0329                             << alignments_.m_align[index].rawId() << "):\n"
0330                             << "\tx: " << alignments_.m_align[index].translation().x()
0331                             << "\ty: " << alignments_.m_align[index].translation().y()
0332                             << "\tz: " << alignments_.m_align[index].translation().z()
0333                             << "\tphi: " << alignments_.m_align[index].rotation().phi()
0334                             << "\ttheta: " << alignments_.m_align[index].rotation().theta()
0335                             << "\tpsi: " << alignments_.m_align[index].rotation().psi()
0336                             << "============================================================\n";
0337       alignments_.m_align[index] = *itAlign;
0338       alignmentErrors_.m_alignError[index] = *itAlignErr;
0339       commonIDs.push_back(id);
0340       LogDebug("Alignment") << "============================================================\n"
0341                             << "Global tag content (" << toString(subDets_[index]) << ", "
0342                             << alignments_.m_align[index].rawId() << "):\n"
0343                             << "\tx: " << alignments_.m_align[index].translation().x()
0344                             << "\ty: " << alignments_.m_align[index].translation().y()
0345                             << "\tz: " << alignments_.m_align[index].translation().z()
0346                             << "\tphi: " << alignments_.m_align[index].rotation().phi()
0347                             << "\ttheta: " << alignments_.m_align[index].rotation().theta()
0348                             << "\tpsi: " << alignments_.m_align[index].rotation().psi()
0349                             << "============================================================\n";
0350     }
0351   }
0352 
0353   // - surface deformations are stored differently
0354   //   -> different treatment
0355   // - the above payloads contain also entries for ideal modules
0356   // - no entry is created for ideal surfaces
0357   //   -> size of surface deformation payload does not necessarily match the
0358   //      size of the other tracker alignment payload
0359   for (const auto& id : commonIDs) {
0360     // search for common raw ID in surface deformation items
0361     auto item = std::find_if(surfaceDeformations->items().cbegin(),
0362                              surfaceDeformations->items().cend(),
0363                              [&id](const auto& i) { return i.m_rawId == id; });
0364     if (item == surfaceDeformations->items().cend())
0365       continue;  // not found
0366 
0367     // copy surface deformation item
0368     const auto index = std::distance(surfaceDeformations->items().cbegin(), item);
0369     const auto beginEndPair = surfaceDeformations->parameters(index);
0370     std::vector<align::Scalar> params(beginEndPair.first, beginEndPair.second);
0371     alignmentSurfaceDeformations_.add(item->m_rawId, item->m_parametrizationType, params);
0372   }
0373 }
0374 
0375 void CreateIdealTkAlRecords::writeToDB() {
0376   const auto& since = cond::timeTypeSpecs[cond::runnumber].beginValue;
0377 
0378   edm::Service<cond::service::PoolDBOutputService> poolDb;
0379   if (!poolDb.isAvailable()) {
0380     throw cms::Exception("NotAvailable") << "PoolDBOutputService not available";
0381   }
0382 
0383   edm::LogInfo("Alignment") << "Writing ideal tracker-alignment records.";
0384   poolDb->writeOneIOV(alignments_, since, "TrackerAlignmentRcd");
0385   poolDb->writeOneIOV(alignmentErrors_, since, "TrackerAlignmentErrorExtendedRcd");
0386   poolDb->writeOneIOV(alignmentSurfaceDeformations_, since, "TrackerSurfaceDeformationRcd");
0387 }
0388 
0389 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0390 void CreateIdealTkAlRecords::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0391   edm::ParameterSetDescription desc;
0392   desc.setComment(
0393       "Creates ideal TrackerAlignmentRcd and TrackerAlignmentErrorExtendedRcd "
0394       "from the loaded tracker geometry. "
0395       "PoolDBOutputService must be set up for these records.");
0396   desc.addUntracked<bool>("alignToGlobalTag", false);
0397   desc.addUntracked<std::vector<std::string> >("skipSubDetectors", std::vector<std::string>{});
0398   desc.addUntracked<bool>("createReferenceRcd", false);
0399   descriptions.add("createIdealTkAlRecords", desc);
0400 }
0401 
0402 //define this as a plug-in
0403 DEFINE_FWK_MODULE(CreateIdealTkAlRecords);