Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-22 04:02:34

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