Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:07:34

0001 #ifndef GEOMETRY_CALOGEOMETRY_CALOGEOMETRYDBEP_H
0002 #define GEOMETRY_CALOGEOMETRY_CALOGEOMETRYDBEP_H 1
0003 
0004 // system include files
0005 #include <memory>
0006 
0007 // user include files
0008 #include "FWCore/Framework/interface/ModuleFactory.h"
0009 #include "FWCore/Framework/interface/ESProducer.h"
0010 #include "FWCore/Utilities/interface/ESGetToken.h"
0011 
0012 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0013 #include "CondFormats/AlignmentRecord/interface/GlobalPositionRcd.h"
0014 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
0015 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
0016 #include "Geometry/CaloGeometry/interface/PreshowerStrip.h"
0017 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
0018 #include "DetectorDescription/Core/interface/DDCompactView.h"
0019 
0020 #include "CondFormats/GeometryObjects/interface/PCaloGeometry.h"
0021 
0022 #include "CondFormats/Alignment/interface/Alignments.h"
0023 
0024 #include <Math/Transform3D.h>
0025 #include <Math/EulerAngles.h>
0026 
0027 //Forward declaration
0028 
0029 //
0030 // class declaration
0031 //
0032 
0033 namespace calogeometryDBEPimpl {
0034   // For U::writeFlag() == true
0035   template <typename T, bool>
0036   struct GeometryTraits {
0037     using TokenType = edm::ESGetToken<CaloSubdetectorGeometry, typename T::AlignedRecord>;
0038 
0039     static TokenType makeToken(edm::ESConsumesCollectorT<typename T::AlignedRecord>& cc) {
0040       return cc.template consumes<CaloSubdetectorGeometry>(
0041           edm::ESInputTag{"", T::producerTag() + std::string("_master")});
0042     }
0043   };
0044 
0045   template <typename T>
0046   struct GeometryTraits<T, false> {
0047     using TokenType = edm::ESGetToken<PCaloGeometry, typename T::PGeometryRecord>;
0048 
0049     static TokenType makeToken(edm::ESConsumesCollectorT<typename T::AlignedRecord>& cc) {
0050       return cc.template consumesFrom<PCaloGeometry, typename T::PGeometryRecord>(edm::ESInputTag{});
0051     }
0052   };
0053 
0054   // For the case of non-existent AlignmentRecord
0055   //
0056   // SFINAE tricks to detect if T::AlignmentRecord exists. Note that
0057   // the declarations of the following are sufficient.
0058   template <typename T>
0059   std::false_type has_AlignmentRecord(...);
0060   template <typename T>
0061   std::true_type has_AlignmentRecord(typename T::AlignmentRecord*);
0062 
0063   template <typename T>
0064   struct HasAlignmentRecord {
0065     static constexpr bool value = std::is_same<decltype(has_AlignmentRecord<T>(nullptr)), std::true_type>::value;
0066   };
0067 
0068   // Then define tokens from alignment record
0069   template <typename T, bool = HasAlignmentRecord<T>::value>
0070   struct AlignmentTokens {
0071     edm::ESGetToken<Alignments, typename T::AlignmentRecord> alignments;
0072     edm::ESGetToken<Alignments, GlobalPositionRcd> globals;
0073   };
0074   template <typename T>
0075   struct AlignmentTokens<T, false> {};
0076 
0077   // Some partial specializations need additional tokens...
0078   template <typename T>
0079   struct AdditionalTokens {
0080     void makeTokens(edm::ESConsumesCollectorT<typename T::AlignedRecord>& cc) {}
0081   };
0082 }  // namespace calogeometryDBEPimpl
0083 
0084 template <class T, class U>
0085 class CaloGeometryDBEP : public edm::ESProducer {
0086 public:
0087   typedef CaloCellGeometry::CCGFloat CCGFloat;
0088   typedef CaloCellGeometry::Pt3D Pt3D;
0089   typedef CaloCellGeometry::Pt3DVec Pt3DVec;
0090   typedef CaloCellGeometry::Tr3D Tr3D;
0091 
0092   using PtrType = std::unique_ptr<CaloSubdetectorGeometry>;
0093   typedef CaloSubdetectorGeometry::TrVec TrVec;
0094   typedef CaloSubdetectorGeometry::DimVec DimVec;
0095   typedef CaloSubdetectorGeometry::IVec IVec;
0096 
0097   CaloGeometryDBEP<T, U>(const edm::ParameterSet& ps) : applyAlignment_(ps.getParameter<bool>("applyAlignment")) {
0098     auto cc = setWhatProduced(this,
0099                               &CaloGeometryDBEP<T, U>::produceAligned,
0100                               edm::es::Label(T::producerTag()));  //+std::string("TEST") ) ) ;
0101 
0102     if constexpr (calogeometryDBEPimpl::HasAlignmentRecord<T>::value) {
0103       if (applyAlignment_) {
0104         alignmentTokens_.alignments =
0105             cc.template consumesFrom<Alignments, typename T::AlignmentRecord>(edm::ESInputTag{});
0106         alignmentTokens_.globals = cc.template consumesFrom<Alignments, GlobalPositionRcd>(edm::ESInputTag{});
0107       }
0108     }
0109     geometryToken_ = calogeometryDBEPimpl::GeometryTraits<T, U::writeFlag()>::makeToken(cc);
0110 
0111     additionalTokens_.makeTokens(cc);
0112   }
0113 
0114   ~CaloGeometryDBEP<T, U>() override {}
0115 
0116   PtrType produceAligned(const typename T::AlignedRecord& iRecord) {
0117     const auto [alignPtr, globalPtr] = getAlignGlobal(iRecord);
0118 
0119     TrVec tvec;
0120     DimVec dvec;
0121     IVec ivec;
0122     std::vector<uint32_t> dins;
0123 
0124     if constexpr (U::writeFlag()) {
0125       const auto& pG = iRecord.get(geometryToken_);
0126 
0127       pG.getSummary(tvec, ivec, dvec, dins);
0128 
0129       U::write(tvec, dvec, ivec, T::dbString());
0130     } else {
0131       const auto& pG = iRecord.get(geometryToken_);
0132 
0133       tvec = pG.getTranslation();
0134       dvec = pG.getDimension();
0135       ivec = pG.getIndexes();
0136     }
0137     //*********************************************************************************************
0138 
0139     const unsigned int nTrParm(tvec.size() / T::k_NumberOfCellsForCorners);
0140 
0141     assert(dvec.size() == T::k_NumberOfShapes * T::k_NumberOfParametersPerShape);
0142 
0143     PtrType ptr = std::make_unique<T>();
0144 
0145     ptr->fillDefaultNamedParameters();
0146 
0147     ptr->allocateCorners(T::k_NumberOfCellsForCorners);
0148 
0149     ptr->allocatePar(dvec.size(), T::k_NumberOfParametersPerShape);
0150 
0151     for (unsigned int i(0); i != T::k_NumberOfCellsForCorners; ++i) {
0152       const unsigned int nPerShape(T::k_NumberOfParametersPerShape);
0153       DimVec dims;
0154       dims.reserve(nPerShape);
0155 
0156       const unsigned int indx(ivec.size() == 1 ? 0 : i);
0157 
0158       DimVec::const_iterator dsrc(dvec.begin() + ivec[indx] * nPerShape);
0159 
0160       for (unsigned int j(0); j != nPerShape; ++j) {
0161         dims.emplace_back(*dsrc);
0162         ++dsrc;
0163       }
0164 
0165       const CCGFloat* myParm(CaloCellGeometry::getParmPtr(dims, ptr->parMgr(), ptr->parVecVec()));
0166 
0167       const DetId id(T::DetIdType::detIdFromDenseIndex(i));
0168 
0169       const unsigned int iGlob(nullptr == globalPtr ? 0 : T::alignmentTransformIndexGlobal(id));
0170 
0171       assert(nullptr == globalPtr || iGlob < globalPtr->m_align.size());
0172 
0173       const AlignTransform* gt(nullptr == globalPtr ? nullptr : &globalPtr->m_align[iGlob]);
0174 
0175       assert(nullptr == gt || iGlob == T::alignmentTransformIndexGlobal(DetId(gt->rawId())));
0176 
0177       const unsigned int iLoc(nullptr == alignPtr ? 0 : T::alignmentTransformIndexLocal(id));
0178 
0179       assert(nullptr == alignPtr || iLoc < alignPtr->m_align.size());
0180 
0181       const AlignTransform* at(nullptr == alignPtr ? nullptr : &alignPtr->m_align[iLoc]);
0182 
0183       assert(nullptr == at || (T::alignmentTransformIndexLocal(DetId(at->rawId())) == iLoc));
0184 
0185       const CaloGenericDetId gId(id);
0186 
0187       Pt3D lRef;
0188       Pt3DVec lc(8, Pt3D(0, 0, 0));
0189       T::localCorners(lc, &dims.front(), i, lRef);
0190 
0191       const Pt3D lBck(0.25 * (lc[4] + lc[5] + lc[6] + lc[7]));  // ctr rear  face in local
0192       const Pt3D lCor(lc[0]);
0193 
0194       //----------------------------------- create transform from 6 numbers ---
0195       const unsigned int jj(i * nTrParm);
0196       Tr3D tr;
0197       const ROOT::Math::Translation3D tl(tvec[jj], tvec[jj + 1], tvec[jj + 2]);
0198       const ROOT::Math::EulerAngles ea(6 == nTrParm ? ROOT::Math::EulerAngles(tvec[jj + 3], tvec[jj + 4], tvec[jj + 5])
0199                                                     : ROOT::Math::EulerAngles());
0200       const ROOT::Math::Transform3D rt(ea, tl);
0201       double xx, xy, xz, dx, yx, yy, yz, dy, zx, zy, zz, dz;
0202       rt.GetComponents(xx, xy, xz, dx, yx, yy, yz, dy, zx, zy, zz, dz);
0203       tr = Tr3D(CLHEP::HepRep3x3(xx, xy, xz, yx, yy, yz, zx, zy, zz), CLHEP::Hep3Vector(dx, dy, dz));
0204 
0205       // now prepend alignment(s) for final transform
0206       const Tr3D atr(nullptr == at ? tr
0207                                    : (nullptr == gt ? at->transform() * tr : at->transform() * gt->transform() * tr));
0208       //--------------------------------- done making transform  ---------------
0209 
0210       const Pt3D gRef(atr * lRef);
0211       const GlobalPoint fCtr(gRef.x(), gRef.y(), gRef.z());
0212       const Pt3D gBck(atr * lBck);
0213       const GlobalPoint fBck(gBck.x(), gBck.y(), gBck.z());
0214       const Pt3D gCor(atr * lCor);
0215       const GlobalPoint fCor(gCor.x(), gCor.y(), gCor.z());
0216 
0217       ptr->newCell(fCtr, fBck, fCor, myParm, id);
0218     }
0219 
0220     ptr->initializeParms();  // initializations; must happen after cells filled
0221 
0222     return ptr;
0223   }
0224 
0225 private:
0226   std::tuple<const Alignments*, const Alignments*> getAlignGlobal(const typename T::AlignedRecord& iRecord) const {
0227     const Alignments* alignPtr(nullptr);
0228     const Alignments* globalPtr(nullptr);
0229     if constexpr (calogeometryDBEPimpl::HasAlignmentRecord<T>::value) {
0230       if (applyAlignment_)  // get ptr if necessary
0231       {
0232         const auto& alignments = iRecord.get(alignmentTokens_.alignments);
0233         // require expected size
0234         assert(alignments.m_align.size() == T::numberOfAlignments());
0235         alignPtr = &alignments;
0236 
0237         const auto& globals = iRecord.get(alignmentTokens_.globals);
0238         globalPtr = &globals;
0239       }
0240     }
0241     return std::make_tuple(alignPtr, globalPtr);
0242   }
0243 
0244   typename calogeometryDBEPimpl::AlignmentTokens<T> alignmentTokens_;
0245   typename calogeometryDBEPimpl::GeometryTraits<T, U::writeFlag()>::TokenType geometryToken_;
0246   typename calogeometryDBEPimpl::AdditionalTokens<T> additionalTokens_;
0247   bool applyAlignment_;
0248 };
0249 
0250 #endif