File indexing completed on 2023-03-17 13:02:26
0001 #ifndef GEOMETRY_CALOGEOMETRY_CALOGEOMETRYDBEP_H
0002 #define GEOMETRY_CALOGEOMETRY_CALOGEOMETRYDBEP_H 1
0003
0004
0005 #include <memory>
0006
0007
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
0028
0029
0030
0031
0032
0033 namespace calogeometryDBEPimpl {
0034
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
0055
0056
0057
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
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
0078 template <typename T>
0079 struct AdditionalTokens {
0080 void makeTokens(edm::ESConsumesCollectorT<typename T::AlignedRecord>& cc) {}
0081 };
0082 }
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()));
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]));
0192 const Pt3D lCor(lc[0]);
0193
0194
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
0206 const Tr3D atr(nullptr == at ? tr
0207 : (nullptr == gt ? at->transform() * tr : at->transform() * gt->transform() * tr));
0208
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();
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_)
0231 {
0232 const auto& alignments = iRecord.get(alignmentTokens_.alignments);
0233
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