File indexing completed on 2024-05-10 02:20:45
0001 #ifndef GEOMETRY_ECALGEOMETRYLOADER_ICC
0002 #define GEOMETRY_ECALGEOMETRYLOADER_ICC
0003
0004 #include "CondFormats/Alignment/interface/AlignTransform.h"
0005 #include "Geometry/CaloEventSetup/interface/CaloGeometryLoader.h"
0006 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
0007 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009
0010 #include "DetectorDescription/Core/interface/DDCompactView.h"
0011 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
0012 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0013 #include "DetectorDescription/Core/interface/DDSolid.h"
0014 #include "DetectorDescription/Core/interface/DDMaterial.h"
0015 #include "DetectorDescription/Core/interface/DDTransform.h"
0016 #include "DetectorDescription/Core/interface/DDCompactView.h"
0017 #include "DetectorDescription/Core/interface/DDExpandedView.h"
0018 #include "DetectorDescription/Core/interface/DDSpecifics.h"
0019 #include "DetectorDescription/Core/interface/DDName.h"
0020 #include "DetectorDescription/Core/interface/DDScope.h"
0021 #include "DetectorDescription/Core/interface/DDFilter.h"
0022
0023 #include "DD4hep/Filter.h"
0024 #include <CLHEP/Units/SystemOfUnits.h>
0025
0026 #include <boost/algorithm/string/predicate.hpp>
0027
0028 #include <vector>
0029
0030
0031 template <class T>
0032 typename CaloGeometryLoader<T>::PtrType CaloGeometryLoader<T>::load(const DDCompactView* cpv,
0033 const Alignments* alignments,
0034 const Alignments* globals) {
0035 PtrType geom = std::make_unique<T>();
0036
0037 makeGeometry(cpv, dynamic_cast<T*>(geom.get()), alignments, globals);
0038
0039 return geom;
0040 }
0041
0042 template <class T>
0043 typename CaloGeometryLoader<T>::PtrType CaloGeometryLoader<T>::load(const cms::DDCompactView* cpv,
0044 const Alignments* alignments,
0045 const Alignments* globals) {
0046 PtrType geom = std::make_unique<T>();
0047
0048 makeGeometry(cpv, dynamic_cast<T*>(geom.get()), alignments, globals);
0049
0050 return geom;
0051 }
0052
0053 template <class T>
0054 void CaloGeometryLoader<T>::makeGeometry(const DDCompactView* cpv,
0055 T* geom,
0056 const Alignments* alignments,
0057 const Alignments* globals) {
0058 DDAndFilter<DDSpecificsMatchesValueFilter, DDSpecificsMatchesValueFilter> filter(
0059 DDSpecificsMatchesValueFilter{DDValue("SensitiveDetector", "EcalSensitiveDetector", 0)},
0060 DDSpecificsMatchesValueFilter{DDValue("ReadOutName", T::hitString(), 0)});
0061
0062 DDFilteredView fv0(*cpv, filter);
0063
0064 fillNamedParams(fv0, geom);
0065
0066 geom->allocateCorners(T::k_NumberOfCellsForCorners);
0067 geom->allocatePar(T::k_NumberOfParametersPerShape * T::k_NumberOfShapes, T::k_NumberOfParametersPerShape);
0068
0069 DDFilteredView fv(*cpv, filter);
0070
0071 unsigned int counter(0);
0072 for (bool doSubDets = fv.firstChild(); doSubDets; doSubDets = fv.nextSibling()) {
0073 const DDSolid& solid(fv.logicalPart().solid());
0074 if (boost::starts_with(solid.name().name(), "EA")) {
0075 continue;
0076 }
0077 ++counter;
0078
0079 const ParmVec& parameters(solid.parameters());
0080
0081 DD3Vector x, y, z;
0082 fv.rotation().GetComponents(x, y, z);
0083 const CLHEP::HepRep3x3 temp(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
0084 const CLHEP::HepRotation hr(temp);
0085 const CLHEP::Hep3Vector h3v(fv.translation().X(), fv.translation().Y(), fv.translation().Z());
0086 const HepGeom::Transform3D ht3d(hr,
0087 k_ScaleFromDDD * h3v);
0088
0089 const DetId id(getDetIdForDDDNode(fv));
0090
0091 const unsigned int which(geom->alignmentTransformIndexLocal(id));
0092
0093 assert(nullptr == alignments || which < alignments->m_align.size());
0094
0095 const AlignTransform* at(nullptr == alignments ? nullptr : &alignments->m_align[which]);
0096
0097 assert(nullptr == at || (geom->alignmentTransformIndexLocal(DetId(at->rawId())) == which));
0098
0099 const unsigned int gIndex(geom->alignmentTransformIndexGlobal(id));
0100
0101 const AlignTransform* globalT(
0102 nullptr == globals ? nullptr : (globals->m_align.size() > gIndex ? &globals->m_align[gIndex] : nullptr));
0103
0104 const HepGeom::Transform3D atr(
0105 nullptr == at ? ht3d
0106 : (nullptr == globalT ? at->transform() * ht3d : at->transform() * globalT->transform() * ht3d));
0107
0108 fillGeom(geom, parameters, atr, id, k_ScaleFromDDD);
0109 }
0110
0111 assert(counter <= T::k_NumberOfCellsForCorners);
0112
0113 geom->initializeParms();
0114 }
0115
0116 template <class T>
0117 void CaloGeometryLoader<T>::makeGeometry(const cms::DDCompactView* cpv,
0118 T* geom,
0119 const Alignments* alignments,
0120 const Alignments* globals) {
0121 cms::DDFilteredView fv(cpv->detector(), cpv->detector()->worldVolume());
0122
0123 fillNamedParams(fv, geom);
0124
0125 geom->allocateCorners(T::k_NumberOfCellsForCorners);
0126 geom->allocatePar(T::k_NumberOfParametersPerShape * T::k_NumberOfShapes, T::k_NumberOfParametersPerShape);
0127
0128 std::string attribute = "ReadOutName";
0129 cms::DDSpecParRefs ref;
0130 const cms::DDSpecParRegistry& mypar = cpv->specpars();
0131 mypar.filter(ref, attribute, T::hitString());
0132 fv.mergedSpecifics(ref);
0133
0134 unsigned int counter(0);
0135 while (fv.firstChild()) {
0136 #ifdef EDM_ML_DEBUG
0137 edm::LogVerbatim("EcalGeom") << "Do child " << fv.name();
0138 #endif
0139 if (boost::starts_with(dd4hep::dd::noNamespace(fv.name()), "EA")) {
0140 continue;
0141 }
0142 ++counter;
0143
0144 const ParmVec& parameters(fv.parameters());
0145
0146 DD3Vector x, y, z;
0147 fv.rotation().GetComponents(x, y, z);
0148 const CLHEP::HepRep3x3 temp(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
0149 const CLHEP::HepRotation hr(temp);
0150 const CLHEP::Hep3Vector h3v(fv.translation().X(), fv.translation().Y(), fv.translation().Z());
0151 const HepGeom::Transform3D ht3d(hr,
0152 k_ScaleFromDD4hep * h3v);
0153
0154 const DetId id(getDetIdForDD4hepNode(fv));
0155
0156 const unsigned int which(geom->alignmentTransformIndexLocal(id));
0157
0158 assert(nullptr == alignments || which < alignments->m_align.size());
0159
0160 const AlignTransform* at(nullptr == alignments ? nullptr : &alignments->m_align[which]);
0161
0162 assert(nullptr == at || (geom->alignmentTransformIndexLocal(DetId(at->rawId())) == which));
0163
0164 const unsigned int gIndex(geom->alignmentTransformIndexGlobal(id));
0165
0166 const AlignTransform* globalT(
0167 nullptr == globals ? nullptr : (globals->m_align.size() > gIndex ? &globals->m_align[gIndex] : nullptr));
0168
0169 const HepGeom::Transform3D atr(
0170 nullptr == at ? ht3d
0171 : (nullptr == globalT ? at->transform() * ht3d : at->transform() * globalT->transform() * ht3d));
0172
0173 fillGeom(geom, parameters, atr, id, k_ScaleFromDD4hep);
0174 }
0175
0176 assert(counter <= T::k_NumberOfCellsForCorners);
0177
0178 geom->initializeParms();
0179 }
0180
0181 template <class T>
0182 unsigned int CaloGeometryLoader<T>::getDetIdForDDDNode(const DDFilteredView& fv) {
0183
0184
0185
0186 const DDGeoHistory& parents(fv.geoHistory());
0187 const DDGeoHistory::size_type psize(parents.size());
0188
0189 EcalBaseNumber baseNumber;
0190 baseNumber.setSize(psize);
0191
0192 for (unsigned int i = 1; i <= psize; ++i) {
0193 baseNumber.addLevel(parents[psize - i].logicalPart().name().name(), parents[psize - i].copyno());
0194 }
0195
0196 return m_scheme.getUnitID(baseNumber);
0197 }
0198
0199 template <class T>
0200 unsigned int CaloGeometryLoader<T>::getDetIdForDD4hepNode(const cms::DDFilteredView& fv) {
0201
0202
0203
0204 const std::string path(fv.path());
0205 auto psize = fv.level();
0206
0207 EcalBaseNumber baseNumber;
0208 baseNumber.setSize(psize);
0209
0210 size_t n = path.find('/') + 1;
0211 #ifdef EDM_ML_DEBUG
0212 edm::LogVerbatim("EcalGeom") << path << " n " << n;
0213 #endif
0214 size_t start = n, startold = n;
0215 std::string det(""), num("");
0216 bool done(false);
0217 for (size_t i = n; i <= path.size(); ++i) {
0218 if (i == path.size() || path[i] == '/') {
0219 num = path.substr(start, i - start);
0220 startold = start = i + 1;
0221 baseNumber.addLevel(det, std::stoi(num));
0222 done = true;
0223 } else if (path[i] == ':') {
0224 startold = start = i + 1;
0225 } else if (path[i] == '_') {
0226 det = done ? path.substr(start, i - start) : path.substr(startold, i - startold);
0227 start = i + 1;
0228 done = false;
0229 }
0230 }
0231 baseNumber.reverse();
0232 #ifdef EDM_ML_DEBUG
0233 edm::LogVerbatim("EcalGeom") << "Base number with " << baseNumber.getLevels() << " levels";
0234 for (int k = 0; k < baseNumber.getLevels(); ++k)
0235 edm::LogVerbatim("EcalGeom") << "[" << k << "] " << baseNumber.getLevelName(k) << ":"
0236 << baseNumber.getCopyNumber(k);
0237 #endif
0238 return m_scheme.getUnitID(baseNumber);
0239 }
0240
0241 #endif