File indexing completed on 2025-01-18 09:14:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DDDigi/DigiKernel.h>
0016 #include <DDDigi/DigiContext.h>
0017 #include <DDDigi/DigiContainerProcessor.h>
0018
0019 #include <DD4hep/Detector.h>
0020 #include <DD4hep/Readout.h>
0021 #include <DD4hep/DetElement.h>
0022 #include <DD4hep/IDDescriptor.h>
0023 #include <DD4hep/Segmentations.h>
0024 #include <DD4hep/DetectorLoad.h>
0025
0026
0027 namespace dd4hep {
0028
0029
0030 namespace digi {
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 class DigiResegment : public DigiContainerProcessor {
0043 protected:
0044 std::string m_detector_name { };
0045 std::string m_readout_name { };
0046 std::string m_readout_descriptor { };
0047 bool m_debug { false };
0048
0049 Readout m_new_readout { };
0050 Segmentation m_new_segment { };
0051 IDDescriptor m_new_id_desc { };
0052 Readout m_org_readout { };
0053 Segmentation m_org_segment { };
0054 IDDescriptor m_org_id_desc { };
0055 DetElement m_detector { };
0056 VolumeManager m_volmgr { };
0057 public:
0058
0059 DigiResegment(const DigiKernel& krnl, const std::string& nam)
0060 : DigiContainerProcessor(krnl, nam)
0061 {
0062 declareProperty("debug", m_debug);
0063 declareProperty("detector", m_detector_name);
0064 declareProperty("readout", m_readout_name);
0065 declareProperty("descriptor", m_readout_descriptor);
0066 m_kernel.register_initialize(std::bind(&DigiResegment::initialize, this));
0067 }
0068
0069 void initialize() {
0070 auto& detector = m_kernel.detectorDescription();
0071 if ( m_readout_descriptor.empty() ) {
0072 except("+++ Invalid ID descriptor %s", m_readout_descriptor.c_str());
0073 }
0074 DetectorLoad loader(detector);
0075 loader.processXMLString(m_readout_descriptor.c_str());
0076 m_new_readout = detector.readout(m_readout_name);
0077 if ( !m_new_readout.isValid() ) {
0078 except("+++ Invalid resegmentation readout for %s", m_readout_name.c_str());
0079 }
0080 m_new_id_desc = m_new_readout.idSpec();
0081 m_new_segment = m_new_readout.segmentation();
0082
0083
0084 m_detector = detector.detector(m_detector_name);
0085 if ( !m_detector.isValid() ) {
0086 except("+++ Cannot locate subdetector: %s", m_detector_name.c_str());
0087 }
0088 m_org_readout = detector.sensitiveDetector(m_detector_name).readout();
0089 if ( !m_org_readout.isValid() ) {
0090 except("+++ Invalid resegmentation readout for %s", m_readout_name.c_str());
0091 }
0092 m_org_id_desc = m_org_readout.idSpec();
0093 m_org_segment = m_org_readout.segmentation();
0094
0095 m_volmgr = detector.volumeManager();
0096 if ( !m_volmgr.isValid() ) {
0097 detector.apply("DD4hepVolumeManager",0,nullptr);
0098 }
0099 m_volmgr = detector.volumeManager();
0100 if ( !m_volmgr.isValid() ) {
0101 except("+++ Cannot locate volume manager!");
0102 }
0103 info("+++ Successfully initialized resegmentation action.");
0104 }
0105
0106 template <typename T> void
0107 resegment_deposits(const T& cont, work_t& work, const predicate_t& predicate) const {
0108 Key key(cont.name, work.environ.output.mask);
0109 DepositVector m(cont.name, key.mask(), cont.data_type);
0110 std::size_t start = m.size();
0111 for( const auto& dep : cont ) {
0112 if( predicate(dep) ) {
0113 CellID cell = dep.first;
0114 auto* ctxt = m_volmgr.lookupContext(cell);
0115 if ( !ctxt ) {
0116 error("+++ Cannot locate volume context for cell %016lX", cell);
0117 }
0118 else {
0119 VolumeID volID = m_org_segment.volumeID(cell);
0120 Position org_local = m_org_segment.position(cell);
0121 Position global = ctxt->localToWorld(org_local);
0122 CellID new_cell = m_new_segment.cellID(org_local, global, volID);
0123 Position new_local = m_new_segment.position(new_cell);
0124 if ( m_debug ) {
0125 info("+++ Cell: %016lX -> %016lX DE: %-20s "
0126 "Pos global: %8.2f %8.2f %8.2f local: %8.2f %8.2f %8.2f -> %8.2f %8.2f %8.2f",
0127 cell, new_cell, ctxt->element.name(),
0128 global.X(), global.Y(), global.Z(),
0129 org_local.X(), org_local.Y(), org_local.Z(),
0130 new_local.X(), new_local.Y(), new_local.Z()
0131 );
0132 }
0133 EnergyDeposit d(dep.second);
0134 d.position = std::move(global);
0135 d.momentum = dep.second.momentum;
0136 m.emplace(new_cell, std::move(d));
0137 }
0138 }
0139 }
0140 std::size_t end = m.size();
0141 work.environ.output.data.put(m.key, std::move(m));
0142 info("+++ %-32s added %6ld entries (now: %6ld) from mask: %04X to mask: %04X",
0143 cont.name.c_str(), end-start, end, cont.key.mask(), m.key.mask());
0144 }
0145
0146
0147 virtual void execute(DigiContext&, work_t& work, const predicate_t& predicate) const override final {
0148 if ( const auto* m = work.get_input<DepositMapping>() )
0149 resegment_deposits(*m, work, predicate);
0150 else if ( const auto* v = work.get_input<DepositVector>() )
0151 resegment_deposits(*v, work, predicate);
0152 else
0153 except("Request to handle unknown data type: %s", work.input_type_name().c_str());
0154 }
0155 };
0156 }
0157 }
0158
0159 #include <DDDigi/DigiFactories.h>
0160 DECLARE_DIGIACTION_NS(dd4hep::digi,DigiResegment)