diff --git a/DDCore/include/DD4hep/VolumeManager.h b/DDCore/include/DD4hep/VolumeManager.h index 9a477813bdc0b35bab86c3b9e28426876f9b1efe..532a42393cafd2ad081eb2f9c61c3cf16f8aea5b 100644 --- a/DDCore/include/DD4hep/VolumeManager.h +++ b/DDCore/include/DD4hep/VolumeManager.h @@ -76,6 +76,14 @@ namespace dd4hep { PlacedVolume elementPlacement() const; /// Access the transformation to the closest detector element const TGeoHMatrix& toElement() const; + /// Transform local coordinates to the DetElement coordinates + Position localToElement(const double local[3]) const; + /// Transform local coordinates to the DetElement coordinates + Position localToElement(const Position& local) const; + /// Transform local coordinates to the world coordinates + Position localToWorld(const double local[3]) const; + /// Transform local coordinates to the world coordinates + Position localToWorld(const Position& local) const; }; /// Class to support the retrieval of detector elements and volumes given a valid identifier diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp index 603eee3b9e2abc964aaba2891ab3b4a5ab2a08da..25744142cac4c44fada7f650d67ea1c53e48e919 100644 --- a/DDCore/src/VolumeManager.cpp +++ b/DDCore/src/VolumeManager.cpp @@ -327,6 +327,34 @@ const TGeoHMatrix& VolumeManagerContext::toElement() const { return ext->toElement; } +/// Transform local coordinates to the DetElement coordinates +Position VolumeManagerContext::localToElement(const double local[3]) const { + double elt[3]; + toElement().LocalToMaster(local, elt); + return { elt[0], elt[1], elt[2] }; +} + +/// Transform local coordinates to the DetElement coordinates +Position VolumeManagerContext::localToElement(const Position& local) const { + double loc[3]; + local.GetCoordinates(loc); + return localToElement(loc); +} + +/// Transform local coordinates to the world coordinates +Position VolumeManagerContext::localToWorld(const double local[3]) const { + double elt[3]; + toElement().LocalToMaster(local, elt); + return element.nominal().localToWorld(elt); +} + +/// Transform local coordinates to the world coordinates +Position VolumeManagerContext::localToWorld(const Position& local) const { + double l[3]; + local.GetCoordinates(l); + return localToWorld(l); +} + /// Initializing constructor to create a new object VolumeManager::VolumeManager(const Detector& description, const string& nam, DetElement elt, Readout ro, int flags) { printout(INFO, "VolumeManager", " - populating volume ids - be patient ..." ); diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index 498b215fb4455e47e130ee7e270a8fd07974d122..9c5ba437fc1e5f86524a29d508ba4094988b2ed2 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -1098,6 +1098,14 @@ template <> void Converter<Readout>::operator()(xml_h e) const { description.addReadout(ro); } +static long load_readout(Detector& description, xml_h element) { + Converter<Readout> converter(description); + converter(element); + return 1; +} +DECLARE_XML_DOC_READER(readout,load_readout) + + /** Specialized converter for compact LimitSet objects. * * <limitset name="...."> diff --git a/DDDigi/ddg4/DigiDDG4Input.cpp b/DDDigi/ddg4/DigiDDG4Input.cpp index 5366b7ba25f758ae96ca69697e1779d4487a8a64..f887b0a4183ed30d5c63513420bd4d8a6c25aac0 100644 --- a/DDDigi/ddg4/DigiDDG4Input.cpp +++ b/DDDigi/ddg4/DigiDDG4Input.cpp @@ -82,12 +82,12 @@ namespace { static void* convert_sim_geant4calorimeter_hits() { return ddg4_hit_convert_function<sim::Geant4Calorimeter::Hit>("DDG4 calorimeter hits"); } -DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Calorimeter_Hit_,convert_sim_geant4calorimeter_hits); +DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Calorimeter_Hit_,convert_sim_geant4calorimeter_hits) static void* convert_sim_geant4tracker_hits() { return ddg4_hit_convert_function<sim::Geant4Tracker::Hit>("DDG4 tracker hits"); } -DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Tracker_Hit_,convert_sim_geant4tracker_hits); +DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Tracker_Hit_,convert_sim_geant4tracker_hits) static void* convert_sim_geant4particles() { func_t* cnv = new func_t([] (DataSegment& segment, int mask, const char* name, void* ptr) { @@ -118,4 +118,4 @@ static void* convert_sim_geant4particles() { }); return cnv; } -DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Particle_,convert_sim_geant4particles); +DECLARE_CREATE(DD4hep_DDDigiConverter_vector_dd4hep_sim_Geant4Particle_,convert_sim_geant4particles) diff --git a/DDDigi/include/DDDigi/DigiAction.h b/DDDigi/include/DDDigi/DigiAction.h index dcb1ed3bf22317ed2d38483cc5e5b92195599fa6..e274ebb2ef80adaef271917e75fe6cdb2a88732b 100644 --- a/DDDigi/include/DDDigi/DigiAction.h +++ b/DDDigi/include/DDDigi/DigiAction.h @@ -105,7 +105,9 @@ namespace dd4hep { long m_refCount = 1; /// Default property: Output level int m_outputLevel = 3; - + /// + std::vector<void*> m_opt_properties; + protected: /// Define standard assignments and constructors DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiAction); @@ -133,7 +135,11 @@ namespace dd4hep { m_name = new_name; } /// Access to the properties of the object - PropertyManager& properties() { + PropertyManager& properties() { + return m_properties; + } + /// Access to the properties of the object (CONST) + const PropertyManager& properties() const { return m_properties; } /// Access the output level @@ -147,10 +153,16 @@ namespace dd4hep { template <typename T> DigiAction& declareProperty(const std::string& nam, T& val); /// Declare property template <typename T> DigiAction& declareProperty(const char* nam, T& val); + /// Declare property + template <typename T> DigiAction& addProperty(const std::string& nam, T& val); + /// Declare property + template <typename T> DigiAction& addProperty(const char* nam, T& val); /// Check property for existence bool hasProperty(const std::string& name) const; /// Access single property Property& property(const std::string& name); + /// Access single property (CONST) + const Property& property(const std::string& name) const; /// Support for messages with variable output level using output level void print(const char* fmt, ...) const; @@ -183,6 +195,23 @@ namespace dd4hep { m_properties.add(nam, val); return *this; } + /// Declare property + template <typename T> DigiAction& DigiAction::addProperty(const std::string& nam, T& val) { + void* ptr = ::operator new(sizeof(T)); + T* prop = new(ptr) T(val); + m_properties.add(nam, *prop); + m_opt_properties.emplace_back(ptr); + return *this; + } + + /// Declare property + template <typename T> DigiAction& DigiAction::addProperty(const char* nam, T& val) { + void* ptr = ::operator new(sizeof(T)); + T* prop = new(ptr) T(val); + m_properties.add(nam, *prop); + m_opt_properties.emplace_back(ptr); + return *this; + } } // End namespace digi } // End namespace dd4hep diff --git a/DDDigi/include/DDDigi/DigiContainerProcessor.h b/DDDigi/include/DDDigi/DigiContainerProcessor.h index 075848e245755e91def3e1e96a90c851de2f7d5b..6cfaf3ff1f16b5fe4e82736b3b262c4664f8eb67 100644 --- a/DDDigi/include/DDDigi/DigiContainerProcessor.h +++ b/DDDigi/include/DDDigi/DigiContainerProcessor.h @@ -10,8 +10,8 @@ // Author : M.Frank // //========================================================================== -#ifndef DDDIGI_DIGIMULTICONTAINERPROCESSOR_H -#define DDDIGI_DIGIMULTICONTAINERPROCESSOR_H +#ifndef DDDIGI_DIGICONTAINERPROCESSOR_H +#define DDDIGI_DIGICONTAINERPROCESSOR_H // Framework include files #include <DDDigi/DigiData.h> @@ -42,7 +42,10 @@ namespace dd4hep { */ class DigiContainerProcessor : public DigiAction { public: - using segment_t = DataSegment; + using segment_t = DataSegment; + using context_t = DigiContext; + using action_t = DigiAction; + using property_t = PropertyManager; struct input_t { /// Input data key Key key; @@ -50,21 +53,18 @@ namespace dd4hep { std::any& data; }; struct output_t { - /// Lock for secure output merging - //std::mutex& lock; - /// Handle to output - //std::any& data; int mask; segment_t& data; }; - struct work_t { /// Event processing context - DigiContext& context; + context_t& context; /// Input data - input_t input; + input_t input; /// Output data - output_t& output; + output_t& output; + /// Optional properties + const property_t& properties; /// Basic check if input data are present bool has_input() const { return this->input.data.has_value(); } @@ -78,22 +78,8 @@ namespace dd4hep { template <typename DATA> DATA* get_input(bool exc=false); /// Access input data by type template <typename DATA> const DATA* get_input(bool exc=false) const; -#if 0 - /// Basic check if input data are present - bool has_output() const { return this->output.data.has_value(); } - /// String form of the output data type - std::string output_type_name() const; - /// Access the output data type - const std::type_info& output_type() const; - /// Access output data by type - template <typename DATA> DATA* get_output(); - - /// Merge output data (thread safe, locked) - void merge_output(DepositVector&& data); - /// Merge output data (thread safe, locked) - void emplace_output(CellID cell, EnergyDeposit&& deposit); -#endif }; + protected: /// Define standard assignments and constructors DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiContainerProcessor); @@ -129,12 +115,12 @@ namespace dd4hep { protected: /// Property to steer parallel processing - bool m_parallel { false }; + bool m_parallel { false }; - /// Array of sub-workers - workers_t m_workers; /// Lock for output merging mutable std::mutex m_output_lock; + /// Array of sub-workers + workers_t m_workers; protected: /// Define standard assignments and constructors @@ -142,6 +128,9 @@ namespace dd4hep { /// Default destructor virtual ~DigiContainerSequence(); + /// Get hold of the registered processor for a given container + worker_t* need_registered_worker(Key item_key) const; + public: /// Standard constructor DigiContainerSequence(const DigiKernel& kernel, const std::string& name); @@ -164,9 +153,11 @@ namespace dd4hep { protected: /// Argument structure for client calls + using action_t = DigiAction; using self_t = DigiContainerSequenceAction; using processor_t = DigiContainerProcessor; using output_t = processor_t::output_t; + using property_t = processor_t::property_t; struct work_item_t { Key key; std::any* data; @@ -175,7 +166,8 @@ namespace dd4hep { DigiContext& context; std::vector<work_item_t> input_items; output_t& output; - const self_t* parent; + const property_t& properties; + const self_t& parent; }; using worker_t = DigiParallelWorker<processor_t, work_t>; using workers_t = DigiParallelWorkers<worker_t>; @@ -197,11 +189,11 @@ namespace dd4hep { /// Property: Input data segment name std::string m_output_segment { "outputs" }; /// Property: event mask for output data - int m_output_mask { 0x0 }; + int m_output_mask { 0x0 }; /// Lock for output merging mutable std::mutex m_output_lock; - + protected: /// Define standard assignments and constructors DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiContainerSequenceAction); @@ -211,6 +203,9 @@ namespace dd4hep { /// Initialization callback virtual void initialize(); + /// Get hold of the registered processor for a given container + worker_t* need_registered_worker(Key item_key) const; + public: /// Standard constructor DigiContainerSequenceAction(const DigiKernel& kernel, const std::string& name); @@ -236,13 +231,15 @@ namespace dd4hep { using worker_keys_t = std::vector<std::vector<Key> >; using work_items_t = std::vector<std::pair<Key, std::any*> >; using output_t = processor_t::output_t; + using property_t = processor_t::property_t; /// Argument structure required to support multiple client calls struct work_t { - DigiContext& context; - work_items_t& items; - output_t& output; - const self_t& parent; + DigiContext& context; + work_items_t& items; + output_t& output; + const property_t& properties; + const self_t& parent; }; using worker_t = DigiParallelWorker<processor_t, work_t>; using workers_t = DigiParallelWorkers<worker_t>; @@ -262,11 +259,12 @@ namespace dd4hep { std::set<Key> m_work_items; /// Set of keys required by each worker worker_keys_t m_worker_keys; - /// Array of sub-workers - workers_t m_workers; /// Lock for output merging mutable std::mutex m_output_lock; + /// Array of sub-workers + workers_t m_workers; + protected: /// Define standard assignments and constructors DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiMultiContainerProcessor); @@ -289,4 +287,4 @@ namespace dd4hep { }; } // End namespace digi } // End namespace dd4hep -#endif // DDDIGI_DIGIMULTICONTAINERPROCESSOR_H +#endif // DDDIGI_DIGICONTAINERPROCESSOR_H diff --git a/DDDigi/include/DDDigi/DigiContext.h b/DDDigi/include/DDDigi/DigiContext.h index 398d3a75d44ca282d1aade24752cb9a78e7f643f..cbd03bb3aa8eece54907a6cde4102d58be1e4c0c 100644 --- a/DDDigi/include/DDDigi/DigiContext.h +++ b/DDDigi/include/DDDigi/DigiContext.h @@ -95,7 +95,10 @@ namespace dd4hep { protected: /// Reference to the random engine for this event std::shared_ptr<DigiRandomGenerator> m_random; - + /// Set the random generator + void set_random_generator(std::shared_ptr<DigiRandomGenerator>& rndm) { + m_random = rndm; + } protected: /// Inhibit default constructor diff --git a/DDDigi/include/DDDigi/DigiData.h b/DDDigi/include/DDDigi/DigiData.h index bf0f6a062255e5e3a73a220464d706851e423b3e..881a489533ea242a530787f54681932428d2deaa 100644 --- a/DDDigi/include/DDDigi/DigiData.h +++ b/DDDigi/include/DDDigi/DigiData.h @@ -220,7 +220,7 @@ namespace dd4hep { inline SegmentEntry::SegmentEntry(const std::string& nam, Key::mask_type msk) : name(nam) { - key.set_mask(msk); + key.set(nam, msk); } /// Particle definition for digitization @@ -343,8 +343,9 @@ namespace dd4hep { double length { 0 }; /// Total energy deposit double deposit { 0 }; - + /// Optional flag for user masks long flag { 0 }; + /// Source mask of this deposit Key::mask_type mask { 0 }; /// Sources contributing to this deposit diff --git a/DDDigi/include/DDDigi/DigiParallelWorkerGroup.h b/DDDigi/include/DDDigi/DigiParallelWorkerGroup.h index e9e51ad76d58142f0fb33e7700fe3bbdb69da266..f1ca58a3c4128965f1ee3f357ecb36a67ae477bf 100644 --- a/DDDigi/include/DDDigi/DigiParallelWorkerGroup.h +++ b/DDDigi/include/DDDigi/DigiParallelWorkerGroup.h @@ -55,6 +55,10 @@ namespace dd4hep { ~DigiParallelWorkerGroup(); /// Access the worker array. As long as the object persists it shall not be altered operator ParallelWorker*const* (); + /// Access specific worker array from group: actors are locked while group exists + std::vector<typename DigiParallelWorkers<T>::worker_t*> actors() { + return workers.actors; + } }; /// Initializin constructor: aquire worker's semaphore diff --git a/DDDigi/include/DDDigi/DigiParallelWorkers.h b/DDDigi/include/DDDigi/DigiParallelWorkers.h index 18dea5ad8173c8d6a934eed0cbb09368e47e5a5f..33f9c8fcb629dbd9f60ebf67b6ac736fa2050ecf 100644 --- a/DDDigi/include/DDDigi/DigiParallelWorkers.h +++ b/DDDigi/include/DDDigi/DigiParallelWorkers.h @@ -51,6 +51,7 @@ namespace dd4hep { private: mutable std::vector<worker_t*> actors; mutable DigiSemaphore semaphore; + std::unique_lock<std::mutex> can_modify() const; public: /// Default constructor @@ -66,16 +67,12 @@ namespace dd4hep { /// Default destructor virtual ~DigiParallelWorkers(); - std::unique_lock<std::mutex> can_modify() const; /// Return array protected worker group group_t get_group() const; - /// NOT thread-safe stuff. Do not use during event processing unless you are sequential - const std::vector<worker_t*>& get() const { return actors; } std::size_t size() const; bool empty() const; bool insert(worker_t* entry) const; - ParallelWorker*const* get_calls() const; }; template <typename T> inline @@ -108,12 +105,6 @@ namespace dd4hep { bool DigiParallelWorkers<T>::empty() const { return actors.empty(); } - - template <typename T> inline - ParallelWorker*const* DigiParallelWorkers<T>::get_calls() const { - return (ParallelWorker**)&this->actors.at(0); - } - template <typename T> inline typename DigiParallelWorkers<T>::group_t DigiParallelWorkers<T>::get_group() const { return group_t(*this); diff --git a/DDDigi/include/DDDigi/DigiRandomGenerator.h b/DDDigi/include/DDDigi/DigiRandomGenerator.h index f7fc4c0cc88c002ea4a98aa760d481d6c8fa7ce8..92f05c2631f101b7cd933e679e59f7c596e198b6 100644 --- a/DDDigi/include/DDDigi/DigiRandomGenerator.h +++ b/DDDigi/include/DDDigi/DigiRandomGenerator.h @@ -67,8 +67,8 @@ namespace dd4hep { double landau (double mean = 0.0, double sigma = 1.0) const; double breitWigner(double mean = 0.0, double gamma = 1.0) const; double poisson(double mean) const; - void rannor(float& a, float& b) const; - void rannor(double& a, double& b) const; + void rannor(float& a, float& b) const; + void rannor(double& a, double& b) const; void sphere(double& x, double& y, double& z, double r) const; void circle(double &x, double &y, double r) const; }; diff --git a/DDDigi/plugins/DigiCellMultiplicyCounter.cpp b/DDDigi/plugins/DigiCellMultiplicyCounter.cpp index 843c735aade5540143eb4ba6dd75cbdcb30b5d3b..e00d47980bfe1d79fbe9dba89120c2797ba97230 100644 --- a/DDDigi/plugins/DigiCellMultiplicyCounter.cpp +++ b/DDDigi/plugins/DigiCellMultiplicyCounter.cpp @@ -17,7 +17,6 @@ /// Namespace for the AIDA detector description toolkit namespace dd4hep { - /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { diff --git a/DDDigi/plugins/DigiDepositMapCreator.cpp b/DDDigi/plugins/DigiDepositMapCreator.cpp index d420822d33477f4dc8d8c87338ed3d3c4dbf686e..233a1f70a58639504acb22edfefcaadd95880bd7 100644 --- a/DDDigi/plugins/DigiDepositMapCreator.cpp +++ b/DDDigi/plugins/DigiDepositMapCreator.cpp @@ -38,18 +38,14 @@ namespace dd4hep { template <typename T> void create_deposits(const T& cont, work_t& work) const { Key key(cont.name, work.output.mask); - DepositMapping* mapping = work.output.data.pointer<DepositMapping>(key); - if ( !mapping ) { - DepositMapping m(cont.name, work.output.mask); - work.output.data.put(m.key, std::move(m)); - mapping = work.output.data.pointer<DepositMapping>(key); - } - std::size_t start = mapping->size(); + DepositMapping m(cont.name, work.output.mask); + std::size_t start = m.size(); for( const auto& dep : cont ) - mapping->data.emplace(dep.first, EnergyDeposit()); - std::size_t end = mapping->size(); + m.data.emplace(dep.first, EnergyDeposit()); + std::size_t end = m.size(); + work.output.data.put(m.key, std::move(m)); info("+++ %-32s added %6ld entries (now: %6ld) from mask: %04X to mask: %04X", - cont.name.c_str(), end-start, end, cont.key.mask(), mapping->key.mask()); + cont.name.c_str(), end-start, end, cont.key.mask(), m.key.mask()); } /// Main functional callback virtual void execute(DigiContext&, work_t& work) const override final { diff --git a/DDDigi/plugins/DigiDepositWeightedPosition.cpp b/DDDigi/plugins/DigiDepositWeightedPosition.cpp new file mode 100644 index 0000000000000000000000000000000000000000..512d13bb7d5b604ef04d070efde33f73e61160de --- /dev/null +++ b/DDDigi/plugins/DigiDepositWeightedPosition.cpp @@ -0,0 +1,64 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include <DDDigi/DigiContext.h> +#include <DDDigi/DigiContainerProcessor.h> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + /// Actor to select energy deposits according to the supplied segmentation + /** Actor to select energy deposits according to the supplied segmentation + * + * The selected deposits are placed in the output container + * supplied by the arguments. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiDepositWeightedPosition : public DigiContainerProcessor { + public: + /// Standard constructor + using DigiContainerProcessor::DigiContainerProcessor; + + template <typename T> void create_deposits(const T& cont, work_t& work) const { + Key key(cont.name, work.output.mask); + DepositMapping m(cont.name, work.output.mask); + std::size_t start = m.size(); + for( const auto& dep : cont ) + m.data.emplace(dep.first, EnergyDeposit()); + std::size_t end = m.size(); + work.output.data.put(m.key, std::move(m)); + info("+++ %-32s added %6ld entries (now: %6ld) from mask: %04X to mask: %04X", + cont.name.c_str(), end-start, end, cont.key.mask(), m.key.mask()); + } + /// Main functional callback + virtual void execute(DigiContext&, work_t& work) const override final { + if ( const auto* m = work.get_input<DepositMapping>() ) + create_deposits(*m, work); + else if ( const auto* v = work.get_input<DepositVector>() ) + create_deposits(*v, work); + else + except("Request to handle unknown data type: %s", work.input_type_name().c_str()); + } + }; + } // End namespace digi +} // End namespace dd4hep + +#include <DDDigi/DigiFactories.h> +DECLARE_DIGIACTION_NS(dd4hep::digi,DigiDepositWeightedPosition) diff --git a/DDDigi/plugins/DigiIPCreate.cpp b/DDDigi/plugins/DigiIPCreate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e92ba6eb8f08faf09b408db496ad7d5092eef95e --- /dev/null +++ b/DDDigi/plugins/DigiIPCreate.cpp @@ -0,0 +1,58 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include <DDDigi/DigiData.h> +#include <DDDigi/DigiEventAction.h> + +/// C/C++ include files +#include <cmath> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + class DigiIPCreate : public DigiEventAction { + Position m_offset_ip; + Position m_sigma_ip; + mutable Position m_interaction_point; + public: + /// Standard constructor + DigiIPCreate(const DigiKernel& krnl, const std::string& nam) + : DigiEventAction(krnl, nam) + { + declareProperty("offset_ip", m_offset_ip); + declareProperty("sigma_ip", m_sigma_ip); + declareProperty("interaction_point", m_interaction_point); + } + /// Main functional callback + virtual void execute(DigiContext& context) const override final { + auto& rndm = context.randomGenerator(); + double theta = rndm.uniform(0.0, M_PI); // theta = [0,pi] + double phi = rndm.uniform(0.0, 2.0*M_PI); // phi = [0,2*pi] + double radius = rndm.uniform(0.0, 1.0); // radius = [0,1] + radius = std::sqrt( -std::log(radius) ); // radius in a gaussian distribution + + double st = std::sin(theta); + double xx = radius * st * std::cos(phi) * m_sigma_ip.X() + m_offset_ip.X(); + double yy = radius * st * std::sin(phi) * m_sigma_ip.Y() + m_offset_ip.Y(); + double zz = radius * std::cos(theta) * m_sigma_ip.Z() + m_offset_ip.Z(); + m_interaction_point = Position(xx, yy, zz); + } + }; + } // End namespace digi +} // End namespace dd4hep + +#include <DDDigi/DigiFactories.h> +DECLARE_DIGIACTION_NS(dd4hep::digi,DigiIPCreate) diff --git a/DDDigi/plugins/DigiIPMover.cpp b/DDDigi/plugins/DigiIPMover.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a3c25836adc28951a4ef877becff0b455cec77f --- /dev/null +++ b/DDDigi/plugins/DigiIPMover.cpp @@ -0,0 +1,78 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include <DDDigi/DigiData.h> +#include <DDDigi/DigiContainerProcessor.h> + +#include <iostream> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + class DigiIPMover : public DigiContainerProcessor { + DigiAction* m_ip_creator { nullptr }; + std::string m_ip_property; + + public: + /// Standard constructor + DigiIPMover(const DigiKernel& krnl, const std::string& nam) + : DigiContainerProcessor(krnl, nam) + { + declareProperty("ip_property", m_ip_property); + declareProperty("ip_creator", m_ip_creator); + } + /// Move IP location of deposits + template <typename T> std::size_t move_deposits(T& cont, const Position& delta) const { + info("+++ %-32s [%6ld] IP: x:%7.3f y:%7.3f z:%7.3f", + cont.name.c_str(), cont.size(), delta.X(), delta.Y(), delta.Z()); + for( auto& dep : cont ) + dep.second.position += delta; + return cont.size(); + } + /// Move IP location of MC particles + template <typename T> std::size_t move_particles(T& cont, const Position& delta) const { + info("+++ %-32s [%6ld] IP: x:%7.3f y:%7.3f z:%7.3f", + cont.name.c_str(), cont.size(), delta.X(), delta.Y(), delta.Z()); + for( auto& p : cont ) { + auto& part = p.second; + part.end_position += delta; + part.start_position += delta; + } + return cont.size(); + } + /// Main functional callback + virtual void execute(DigiContext&, work_t& work) const override { + Position delta; + if ( m_ip_creator ) { + m_ip_creator->property(m_ip_property).value(delta); + if ( auto* m = work.get_input<DepositMapping>() ) + move_deposits(*m, delta); + else if ( auto* v = work.get_input<DepositVector>() ) + move_deposits(*v, delta); + else if ( auto* p = work.get_input<ParticleMapping>() ) + move_particles(*p, delta); + else + except("Request to handle unknown data type: %s", work.input_type_name().c_str()); + return; + } + except("+++ No IP creator action known. Did you set the properties: ip_creator and ip_property?"); + } + }; + } // End namespace digi +} // End namespace dd4hep + +#include <DDDigi/DigiFactories.h> +DECLARE_DIGIACTION_NS(dd4hep::digi,DigiIPMover) diff --git a/DDDigi/plugins/DigiIPRandomizer.cpp b/DDDigi/plugins/DigiIPRandomizer.cpp deleted file mode 100644 index 39ec5180874262474c9e1adfa71ad81dd40ddff5..0000000000000000000000000000000000000000 --- a/DDDigi/plugins/DigiIPRandomizer.cpp +++ /dev/null @@ -1,131 +0,0 @@ -//========================================================================== -// AIDA Detector description implementation -//-------------------------------------------------------------------------- -// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) -// All rights reserved. -// -// For the licensing terms see $DD4hepINSTALL/LICENSE. -// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. -// -// Author : M.Frank -// -//========================================================================== - -// Framework include files -#include <DD4hep/InstanceCount.h> -#include <DDDigi/DigiData.h> -#include <DDDigi/DigiContext.h> -#include <DDDigi/DigiEventAction.h> -#include <DDDigi/DigiParallelWorker.h> - - -/// Namespace for the AIDA detector description toolkit -namespace dd4hep { - - /// Namespace for the Digitization part of the AIDA detector description toolkit - namespace digi { - - /// Default base class for all Digitizer actions and derivates thereof. - /** - * This is a utility class supporting properties, output and access to - * event and run objects through the context. - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_DIGITIZATION - */ - class DigiIPRandomizer : public DigiEventAction { - protected: - /// Property: Masks to act on - int m_mask { 0 }; - /// Property: Input data segment name - std::string m_input { }; - - struct worker_args { - std::size_t num_hit { 0 }; - std::size_t num_particle { 0 }; - std::any* container { nullptr }; - worker_args(std::any* p) : container(p) {} - }; - struct work_t { - DigiContext& context; - Position ip_move; - std::vector<worker_args> args; - }; - class work_definition_t; - using self_t = DigiIPRandomizer; - using Worker = DigiParallelWorker<self_t,work_t>; - using Workers = DigiParallelWorkers<Worker>; - - /// Worker objects to be submitted to the kernel - Workers m_workers; - - protected: - /// Define standard assignments and constructors - DDDIGI_DEFINE_ACTION_CONSTRUCTORS(DigiIPRandomizer); - - /// Default destructor - virtual ~DigiIPRandomizer() { - InstanceCount::decrement(this); - } - - Position ip_displacement() const { - return Position(0,0,0); - } - - public: - /// Standard constructor - DigiIPRandomizer(const DigiKernel& krnl, const std::string& nam) - : DigiEventAction(krnl, nam) - { - declareProperty("mask", m_mask); - declareProperty("input_segment", m_input = "inputs"); - InstanceCount::increment(this); - } - /// Main functional callback - virtual void execute(DigiContext& context) const final { - auto& inputs = context.event->get_segment(m_input); - std::vector<worker_args> collection_args; - collection_args.reserve(inputs.size()); - for ( auto& i : inputs ) { - Key key(i.first); - if ( key.mask() == m_mask ) { - collection_args.emplace_back(worker_args(&i.second)); - } - } - work_t data { context, ip_displacement(), collection_args }; - for( auto& c : collection_args ) { - if ( DepositMapping* m = std::any_cast<DepositMapping>(c.container) ) { - for( auto& dep : *m ) - dep.second.position += data.ip_move; - c.num_hit += m->size(); - } - else if ( DepositVector* v = std::any_cast<DepositVector>(c.container) ) { - for( auto& dep : *v ) - dep.second.position += data.ip_move; - c.num_hit += v->size(); - } - else if ( ParticleMapping* parts = std::any_cast<ParticleMapping>(c.container) ) { - for( auto& p : *parts ) { - auto& part = p.second; - part.end_position += data.ip_move; - part.start_position += data.ip_move; - } - c.num_particle += parts->size(); - } - } - std::size_t num_hit = 0; - std::size_t num_particle = 0; - for( const auto& c : collection_args ) { - num_hit += c.num_hit; - num_particle += c.num_particle; - } - info("%s+++ Moved coordinates of %6ld hits ans %6ld particles", - context.event->id(), num_hit, num_particle); - } - }; - } // End namespace digi -} // End namespace dd4hep - -#include <DDDigi/DigiFactories.h> -DECLARE_DIGIACTION_NS(dd4hep::digi,DigiIPRandomizer) diff --git a/DDDigi/plugins/DigiResegment.cpp b/DDDigi/plugins/DigiResegment.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e70ac5eb741161f77d8f96f062ed19ae37b1f22c --- /dev/null +++ b/DDDigi/plugins/DigiResegment.cpp @@ -0,0 +1,157 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Framework include files +#include <DDDigi/DigiKernel.h> +#include <DDDigi/DigiContext.h> +#include <DDDigi/DigiContainerProcessor.h> + +#include <DD4hep/Detector.h> +#include <DD4hep/Readout.h> +#include <DD4hep/DetElement.h> +#include <DD4hep/IDDescriptor.h> +#include <DD4hep/Segmentations.h> +#include <DD4hep/DetectorLoad.h> + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + + /// Actor to select energy deposits according to the supplied segmentation + /** Actor to select energy deposits according to the supplied segmentation + * + * The selected deposits are placed in the output container + * supplied by the arguments. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_DIGITIZATION + */ + class DigiResegment : public DigiContainerProcessor { + protected: + std::string m_detector_name { }; + std::string m_readout_name { }; + std::string m_readout_descriptor { }; + bool m_debug { false }; + + Readout m_new_readout { }; + Segmentation m_new_segment { }; + IDDescriptor m_new_id_desc { }; + Readout m_org_readout { }; + Segmentation m_org_segment { }; + IDDescriptor m_org_id_desc { }; + DetElement m_detector { }; + VolumeManager m_volmgr { }; + public: + /// Standard constructor + DigiResegment(const DigiKernel& krnl, const std::string& nam) + : DigiContainerProcessor(krnl, nam) + { + declareProperty("debug", m_debug); + declareProperty("detector", m_detector_name); + declareProperty("readout", m_readout_name); + declareProperty("descriptor", m_readout_descriptor); + m_kernel.register_initialize(Callback(this).make(&DigiResegment::initialize)); + } + + void initialize() { + auto& detector = m_kernel.detectorDescription(); + if ( m_readout_descriptor.empty() ) { + except("+++ Invalid ID descriptor %s", m_readout_descriptor.c_str()); + } + DetectorLoad loader(detector); + loader.processXMLString(m_readout_descriptor.c_str()); + m_new_readout = detector.readout(m_readout_name); + if ( !m_new_readout.isValid() ) { + except("+++ Invalid resegmentation readout for %s", m_readout_name.c_str()); + } + m_new_id_desc = m_new_readout.idSpec(); + m_new_segment = m_new_readout.segmentation(); + + + m_detector = detector.detector(m_detector_name); + if ( !m_detector.isValid() ) { + except("+++ Cannot locate subdetector: %s", m_detector_name.c_str()); + } + m_org_readout = detector.sensitiveDetector(m_detector_name).readout(); + if ( !m_org_readout.isValid() ) { + except("+++ Invalid resegmentation readout for %s", m_readout_name.c_str()); + } + m_org_id_desc = m_org_readout.idSpec(); + m_org_segment = m_org_readout.segmentation(); + + m_volmgr = detector.volumeManager(); + if ( !m_volmgr.isValid() ) { + detector.apply("DD4hepVolumeManager",0,nullptr); + } + m_volmgr = detector.volumeManager(); + if ( !m_volmgr.isValid() ) { + except("+++ Cannot locate volume manager!"); + } + info("+++ Successfully initialized resegmentation action."); + } + + template <typename T> void resegment_deposits(const T& cont, work_t& work) const { + Key key(cont.name, work.output.mask); + DepositVector m(cont.name, work.output.mask); + std::size_t start = m.size(); + for( const auto& dep : cont ) { + CellID cell = dep.first; + auto* ctxt = m_volmgr.lookupContext(cell); + if ( !ctxt ) { + error("+++ Cannot locate volume context for cell %016lX", cell); + } + else { + VolumeID volID = m_org_segment.volumeID(cell); + Position org_local = m_org_segment.position(cell); + Position global = ctxt->localToWorld(org_local); + CellID new_cell = m_new_segment.cellID(org_local, global, volID); + Position new_local = m_new_segment.position(new_cell); + if ( m_debug ) { + info("+++ Cell: %016lX -> %016lX DE: %-20s " + "Pos global: %8.2f %8.2f %8.2f local: %8.2f %8.2f %8.2f -> %8.2f %8.2f %8.2f", + cell, new_cell, ctxt->element.name(), + global.X(), global.Y(), global.Z(), + org_local.X(), org_local.Y(), org_local.Z(), + new_local.X(), new_local.Y(), new_local.Z() + ); + } + EnergyDeposit d(dep.second); + d.position = global; + d.momentum = dep.second.momentum; + m.emplace(new_cell, std::move(d)); + } + } + std::size_t end = m.size(); + work.output.data.put(m.key, std::move(m)); + info("+++ %-32s added %6ld entries (now: %6ld) from mask: %04X to mask: %04X", + cont.name.c_str(), end-start, end, cont.key.mask(), m.key.mask()); + } + + /// Main functional callback + virtual void execute(DigiContext&, work_t& work) const override final { + if ( const auto* m = work.get_input<DepositMapping>() ) + resegment_deposits(*m, work); + else if ( const auto* v = work.get_input<DepositVector>() ) + resegment_deposits(*v, work); + else + except("Request to handle unknown data type: %s", work.input_type_name().c_str()); + } + }; + } // End namespace digi +} // End namespace dd4hep + +#include <DDDigi/DigiFactories.h> +DECLARE_DIGIACTION_NS(dd4hep::digi,DigiResegment) diff --git a/DDDigi/plugins/DigiSegmentDepositExtractor.cpp b/DDDigi/plugins/DigiSegmentDepositExtractor.cpp index ac3788d30bb034868695a24b1c694c46f0ee5f08..3bb3b4e69d37374c5c9b855941e1ce05de2cec21 100644 --- a/DDDigi/plugins/DigiSegmentDepositExtractor.cpp +++ b/DDDigi/plugins/DigiSegmentDepositExtractor.cpp @@ -17,7 +17,6 @@ /// Namespace for the AIDA detector description toolkit namespace dd4hep { - /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { diff --git a/DDDigi/plugins/DigiSegmentDepositPrint.cpp b/DDDigi/plugins/DigiSegmentDepositPrint.cpp index e4046cfe8feb851fc4eed362bea7fdfb71952de2..471201ecfacba642be1ad0ab8c269240272ae7fd 100644 --- a/DDDigi/plugins/DigiSegmentDepositPrint.cpp +++ b/DDDigi/plugins/DigiSegmentDepositPrint.cpp @@ -17,7 +17,6 @@ /// Namespace for the AIDA detector description toolkit namespace dd4hep { - /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { diff --git a/DDDigi/python/DDDigiDict.C b/DDDigi/python/DDDigiDict.C index 9ba59a6a1e40a066019a3b9e66d048ab1157c2a4..9d39b3223ee120afbb98be209aea0feaf1aed0ad 100644 --- a/DDDigi/python/DDDigiDict.C +++ b/DDDigi/python/DDDigiDict.C @@ -47,6 +47,9 @@ namespace dd4hep { /// Namespace for the Digitization part of the AIDA detector description toolkit namespace digi { + template <typename VAL> + int add_action_property(DigiAction* action, const std::string& name, VAL value); + #define ACTIONHANDLE(x) \ struct x##Handle { \ Digi##x* action; \ @@ -106,6 +109,35 @@ namespace dd4hep { } return 0; } + +#define MKVAL auto val = value + +#define ADD_PROPERTY(n,X) \ + static int add##n (DigiAction* action, const std::string& name, const X value) \ + { return add_action_property(action, name, value); } \ + static int addVector##n (DigiAction* action, const std::string& name, std::vector<X> value) \ + { MKVAL; return add_action_property(action, name, val); } \ + static int addList##n (DigiAction* action, const std::string& name, std::list<X> value) \ + { MKVAL; return add_action_property(action, name, val); } \ + static int addSet##n (DigiAction* action, const std::string& name, std::set<X> value) \ + { MKVAL; return add_action_property(action, name, val); } \ + static int addMapped##n (DigiAction* action, const std::string& name, std::map<std::string,X> value) \ + { MKVAL; return add_action_property(action, name, val); } + ADD_PROPERTY(Property,int) + ADD_PROPERTY(Property,short) + ADD_PROPERTY(Property,size_t) + ADD_PROPERTY(Property,double) + + ADD_PROPERTY(Property,std::string) + + static int addPositionProperty(DigiAction* action, const std::string& name, const std::string value) { + Position pos; + Property pr(pos); + pr.str(value); + return add_action_property(action, name, pos); + } + //ADD_PROPERTY(PositionProperty,dd4hep::Position) + static PropertyResult getPropertyKernel(DigiKernel* kernel, const std::string& name) { if ( kernel->hasProperty(name) ) { return PropertyResult(kernel->property(name).str(),1); diff --git a/DDDigi/python/dddigi.py b/DDDigi/python/dddigi.py index 323d6d9d0dd6a9b96682d14363cf0d5b2a5bd22b..c38dffca50a770b105b9cbb01eb7af9fcb11d720 100644 --- a/DDDigi/python/dddigi.py +++ b/DDDigi/python/dddigi.py @@ -158,6 +158,36 @@ def _setKernelProperty(self, name, value): raise KeyError(msg) +# --------------------------------------------------------------------------- +def _add_property(self, name, value): + Interface.addProperty(self.get(), str(name), value) + + +# --------------------------------------------------------------------------- +def _add_position_property(self, name, value): + Interface.addPositionProperty(self.get(), str(name), str(value)) + + +# --------------------------------------------------------------------------- +def _add_set_property(self, name, value): + Interface.addSetProperty(self.get(), str(name), value) + + +# --------------------------------------------------------------------------- +def _add_list_property(self, name, value): + Interface.addListProperty(self.get(), str(name), value) + + +# --------------------------------------------------------------------------- +def _add_vector_property(self, name, value): + Interface.addVectorProperty(self.get(), str(name), value) + + +# --------------------------------------------------------------------------- +def _add_mapped_property(self, name, value): + Interface.addMappedProperty(self.get(), str(name), value) + + # --------------------------------------------------------------------------- def _kernel_terminate(self): return self.get().terminate() @@ -169,7 +199,12 @@ Kernel.__setattr__ = _setKernelProperty Kernel.terminate = _kernel_terminate # --------------------------------------------------------------------------- ActionHandle = digi.ActionHandle - +ActionHandle.add_property = _add_property +ActionHandle.add_position_property = _add_position_property +ActionHandle.add_set_property = _add_set_property +ActionHandle.add_list_property = _add_list_property +ActionHandle.add_vector_property = _add_vector_property +ActionHandle.add_mapped_property = _add_mapped_property # --------------------------------------------------------------------------- def TestAction(kernel, nam, sleep=0): @@ -205,8 +240,8 @@ def _adopt_processor_action(self, action, container): proc = Interface.toContainerProcessor(action.get()) attr(proc, container) else: - proc = action ##Interface.toContainerProcessor(action) - print(str(proc.__class__)) + proc = action + # print(str(proc.__class__)) attr(proc, container) # print('ContainerProcessor succesfully adopted') # --------------------------------------------------------------------------- diff --git a/DDDigi/src/DigiAction.cpp b/DDDigi/src/DigiAction.cpp index 4443ba1379fd4f514eb54e513903c2001c97cabe..faff69356e16bd1e5a7e5e8461961bdf40cef33e 100644 --- a/DDDigi/src/DigiAction.cpp +++ b/DDDigi/src/DigiAction.cpp @@ -47,6 +47,9 @@ DigiAction::DigiAction(const DigiKernel& krnl, const std::string& nam) /// Default destructor DigiAction::~DigiAction() { + for(auto* ptr : m_opt_properties) + ::operator delete(ptr); + m_opt_properties.clear(); InstanceCount::decrement(this); } @@ -83,6 +86,11 @@ dd4hep::Property& DigiAction::property(const std::string& nam) { return properties()[nam]; } +/// Access single property +const dd4hep::Property& DigiAction::property(const std::string& nam) const { + return properties()[nam]; +} + /// Support for messages with variable output level using output level void DigiAction::print(const char* fmt, ...) const { int level = std::max(int(outputLevel()),(int)VERBOSE); @@ -105,34 +113,42 @@ std::string DigiAction::format(const char* fmt, ...) const { /// Support of debug messages. void DigiAction::debug(const char* fmt, ...) const { - va_list args; - va_start(args, fmt); - dd4hep::printout(dd4hep::DEBUG, m_name, fmt, args); - va_end(args); + if ( std::max(int(outputLevel()),(int)VERBOSE) >= DEBUG ) { + va_list args; + va_start(args, fmt); + dd4hep::printout(dd4hep::DEBUG, m_name, fmt, args); + va_end(args); + } } /// Support of info messages. void DigiAction::info(const char* fmt, ...) const { - va_list args; - va_start(args, fmt); - dd4hep::printout(dd4hep::INFO, m_name, fmt, args); - va_end(args); + if ( std::max(int(outputLevel()),(int)VERBOSE) >= INFO ) { + va_list args; + va_start(args, fmt); + dd4hep::printout(dd4hep::INFO, m_name, fmt, args); + va_end(args); + } } /// Support of warning messages. void DigiAction::warning(const char* fmt, ...) const { - va_list args; - va_start(args, fmt); - dd4hep::printout(dd4hep::WARNING, m_name, fmt, args); - va_end(args); + if ( std::max(int(outputLevel()),(int)VERBOSE) >= WARNING ) { + va_list args; + va_start(args, fmt); + dd4hep::printout(dd4hep::WARNING, m_name, fmt, args); + va_end(args); + } } /// Action to support error messages. void DigiAction::error(const char* fmt, ...) const { - va_list args; - va_start(args, fmt); - dd4hep::printout(dd4hep::ERROR, m_name, fmt, args); - va_end(args); + if ( std::max(int(outputLevel()),(int)VERBOSE) >= ERROR ) { + va_list args; + va_start(args, fmt); + dd4hep::printout(dd4hep::ERROR, m_name, fmt, args); + va_end(args); + } } /// Action to support error messages. @@ -161,3 +177,70 @@ void DigiAction::except(const char* fmt, ...) const { va_end(args); throw std::runtime_error(err); } + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Digitization part of the AIDA detector description toolkit + namespace digi { + template <typename VAL> + int add_action_property(DigiAction* action, const std::string& name, VAL value) { + action->addProperty(name, value); + printout(INFO, "addProperty", "+++ Added property %s of type %s", + name.c_str(), typeName(typeid(VAL)).c_str()); + return 1; + } + +#define ADD_SINGLE_PROPERTY(X) \ + template int add_action_property<X>(DigiAction* action, const std::string& name, X value); + +#define ADD_MAPPED_PROPERTY(K,X) \ + template int add_action_property<std::map<std::string,X> >(DigiAction* action, const std::string& name, std::map<K,X> value); + +#define ADD_PROPERTY(X) \ + ADD_SINGLE_PROPERTY(X) \ + ADD_SINGLE_PROPERTY(std::set<X>) \ + ADD_SINGLE_PROPERTY(std::list<X>) \ + ADD_SINGLE_PROPERTY(std::vector<X>) \ + ADD_MAPPED_PROPERTY(std::string,X) + + ADD_PROPERTY(int) + ADD_PROPERTY(float) + ADD_PROPERTY(double) + ADD_PROPERTY(std::string) + ADD_PROPERTY(dd4hep::Position) + + ADD_SINGLE_PROPERTY(size_t) + } +} + +#include "DD4hep/GrammarUnparsed.h" +namespace dd4hep { + + static bool _from_string(const BasicGrammar&, void* ptr, const std::string& value) { + static constexpr const char MATCH[] = " object at 0x"; + size_t idx = value.find(MATCH); + if ( idx != std::string::npos ) { + void* p = 0; + const char* cptr = value.c_str()+idx+strlen(MATCH)-2; + if ( 1 == ::sscanf(cptr,"%p", &p) ) { + *(void**)ptr = p; + return true; + } + } + dd4hep::except("FAIL","FAIL"); + return false; + } + + template <> const GrammarRegistry& GrammarRegistry::pre_note<DigiAction*>(int) { + BasicGrammar::specialization_t spec; + spec.bind = nullptr; + spec.copy = nullptr; + spec.eval = nullptr; + spec.str = nullptr; + spec.fromString = _from_string; + return pre_note_specs<DigiAction*>(spec); + } +} + +static auto s_registry = dd4hep::GrammarRegistry::pre_note<DigiAction*>(1); diff --git a/DDDigi/src/DigiContainerCombine.cpp b/DDDigi/src/DigiContainerCombine.cpp index 8d9ec05859a6044c0564dd24e9af6a459306f52a..eaa84a2ad65f50628f8add3351a79e5aa2db00a3 100644 --- a/DDDigi/src/DigiContainerCombine.cpp +++ b/DDDigi/src/DigiContainerCombine.cpp @@ -66,7 +66,7 @@ public: cnt = output.merge(std::move(input)); else cnt = output.insert(input); - combine->info(this->format, thr, input.name.c_str(), input.key.values.mask, cnt, "deposits"); + combine->debug(this->format, thr, input.name.c_str(), input.key.values.mask, cnt, "deposits"); this->cnt_depos += cnt; this->cnt_conts++; } @@ -96,7 +96,7 @@ public: if ( keys[j].item() == key.item() ) { ParticleMapping* next = std::any_cast<ParticleMapping>(work[j]); std::size_t cnt = out.merge(std::move(*next)); - combine->info(format, thr, next->name.c_str(), keys[j].mask(), cnt, "particles"); + combine->debug(format, thr, next->name.c_str(), keys[j].mask(), cnt, "particles"); cnt_parts += cnt; cnt_conts++; work[j]->reset(); @@ -190,7 +190,7 @@ void DigiContainerCombine::initialize() { /// Initializing function: compute values which depend on properties void DigiContainerCombine::have_workers(size_t count) const { if ( m_workers.size() < count ) { - auto lock = m_workers.can_modify(); + auto group = m_workers.get_group(); // Lock worker group for(size_t i=m_workers.size(); i <= count; ++i) m_workers.insert(new Worker(nullptr, i)); } diff --git a/DDDigi/src/DigiContainerProcessor.cpp b/DDDigi/src/DigiContainerProcessor.cpp index fe22e51ed4c5bf18cbe6166d43444616aebd96d9..02b1af906501c3c8035073448af2e5cd27e9a96e 100644 --- a/DDDigi/src/DigiContainerProcessor.cpp +++ b/DDDigi/src/DigiContainerProcessor.cpp @@ -58,23 +58,6 @@ namespace dd4hep { } return nullptr; } -#if 0 - template <typename T> T* DigiContainerProcessor::work_t::get_output() { - if ( !output.data.has_value() ) { - T data; - output.data = std::move(data); - } - T* v = std::any_cast<T>(&output.data); - if ( v ) { - return v; - } - dd4hep::except("DigiContainerProcessor", - "+++ Cannot access output. Invalid data handle of type: %s", - output_type_name().c_str()); - return nullptr; - } -#endif - } // End namespace digi } // End namespace dd4hep @@ -95,33 +78,6 @@ std::string DigiContainerProcessor::work_t::input_type_name() const { return typeName(input.data.type()); } -#if 0 -template DepositVector* DigiContainerProcessor::work_t::get_output(); -template DepositMapping* DigiContainerProcessor::work_t::get_output(); -template ParticleMapping* DigiContainerProcessor::work_t::get_output(); - -/// output data type -const std::type_info& DigiContainerProcessor::work_t::output_type() const { - return output.data.type(); -} - -/// String form of the output data type -std::string DigiContainerProcessor::work_t::output_type_name() const { - return typeName(input.data.type()); -} - -/// Merge output data -void DigiContainerProcessor::work_t::merge_output(DepositVector&& data) { - std::lock_guard<std::mutex> lock(output.lock); - this->get_output<DepositVector>()->merge(std::move(data)); -} - -void DigiContainerProcessor::work_t::emplace_output(CellID cell, EnergyDeposit&& data) { - std::lock_guard<std::mutex> lock(output.lock); - this->get_output<DepositVector>()->emplace(cell, std::move(data)); -} -#endif - /// Standard constructor DigiContainerProcessor::DigiContainerProcessor(const DigiKernel& kernel, const std::string& name) : DigiAction(kernel, name) @@ -169,7 +125,7 @@ void DigiContainerSequence::adopt_processor(DigiContainerProcessor* action) { /// Main functional callback if specific work is known void DigiContainerSequence::execute(DigiContext& /* context */, work_t& work) const { - m_kernel.submit(m_workers.get_calls(), m_workers.size(), &work, m_parallel); + m_kernel.submit(m_workers.get_group(), m_workers.size(), &work, m_parallel); } /// Worker adaptor for caller DigiContainerSequence @@ -184,10 +140,10 @@ template <> void DigiParallelWorker<DigiContainerProcessor, DigiContainerSequenceAction::DigiContainerSequenceAction(const DigiKernel& krnl, const std::string& nam) : DigiEventAction(krnl, nam) { - declareProperty("input_mask", m_input_mask); - declareProperty("input_segment", m_input_segment); - declareProperty("output_mask", m_output_mask); - declareProperty("output_segment", m_output_segment); + declareProperty("input_mask", m_input_mask); + declareProperty("input_segment", m_input_segment); + declareProperty("output_mask", m_output_mask); + declareProperty("output_segment", m_output_segment); m_kernel.register_initialize(Callback(this).make(&DigiContainerSequenceAction::initialize)); InstanceCount::increment(this); } @@ -242,6 +198,19 @@ void DigiContainerSequenceAction::adopt_processor(DigiContainerProcessor* action } } +/// Get hold of the registered processor for a given container +DigiContainerSequenceAction::worker_t* +DigiContainerSequenceAction::need_registered_worker(Key item_key) const { + Key key; + key.set_item(item_key.item()); + auto it = m_registered_workers.find(key.item()); + if ( it != m_registered_workers.end() ) { + return it->second; + } + except("No worker registered for input: %016lX", key.key); + return nullptr; +} + /// Main functional callback if specific work is known void DigiContainerSequenceAction::execute(DigiContext& context) const { auto& event = *context.event; @@ -249,14 +218,14 @@ void DigiContainerSequenceAction::execute(DigiContext& context) const { auto& outputs = event.get_segment(m_output_segment); std::vector<ParallelWorker*> event_workers; output_t output { m_output_mask, outputs }; - work_t args { context, {}, output, this }; + work_t args { context, {}, output, m_properties, *this }; args.input_items.resize(m_workers.size(), {0, nullptr}); event_workers.reserve(inputs.size()); for( auto& i : inputs ) { Key key(i.first); if ( key.mask() == m_input_mask ) { - auto it = m_registered_workers.find(key); + auto it = m_registered_workers.find(key.item()); if ( it != m_registered_workers.end() ) { worker_t* w = it->second; event_workers.emplace_back(w); @@ -275,7 +244,7 @@ template <> void DigiParallelWorker<DigiContainerProcessor, std::size_t>::execute(void* data) const { calldata_t* args = reinterpret_cast<calldata_t*>(data); auto& item = args->input_items[this->options]; - DigiContainerProcessor::work_t work { args->context, { item.key, *item.data }, args->output }; + DigiContainerProcessor::work_t work {args->context, {item.key, *item.data}, args->output, args->properties}; action->execute(args->context, work); } @@ -336,10 +305,10 @@ void DigiMultiContainerProcessor::execute(DigiContext& context) const { } } if ( !work_items.empty() ) { - auto& outputs = event.get_segment(m_output_segment); - output_t output { m_output_mask, outputs }; - work_t args { context, work_items, output, *this }; - m_kernel.submit(m_workers.get_calls(), m_workers.size(), &args, m_parallel); + auto& outputs = event.get_segment(m_output_segment); + output_t output { m_output_mask, outputs }; + work_t args { context, work_items, output, properties(), *this }; + m_kernel.submit(m_workers.get_group(), m_workers.size(), &args, m_parallel); } } @@ -348,17 +317,18 @@ template <> void DigiParallelWorker<DigiContainerProcessor, DigiMultiContainerProcessor::work_t, std::size_t>::execute(void* data) const { calldata_t* arg = reinterpret_cast<calldata_t*>(data); - const auto& keys = arg->parent.worker_keys(this->options); - const auto& masks = arg->parent.input_masks(); + const auto& par = arg->parent; + const auto& keys = par.worker_keys(this->options); + const auto& masks = par.input_masks(); for( const auto& item : arg->items ) { Key key = item.first; if ( masks.empty() || std::find(masks.begin(), masks.end(), key.mask()) != masks.end() ) { if ( keys.empty() ) { - DigiContainerProcessor::work_t work {arg->context, {key, *item.second }, arg->output }; + DigiContainerProcessor::work_t work {arg->context, {key, *item.second }, arg->output, arg->properties }; action->execute(work.context, work); } else if ( std::find(keys.begin(), keys.end(), Key(key.item())) != keys.end() ) { - DigiContainerProcessor::work_t work {arg->context, {key, *item.second }, arg->output }; + DigiContainerProcessor::work_t work {arg->context, {key, *item.second }, arg->output, arg->properties }; action->execute(work.context, work); } } diff --git a/DDDigi/src/DigiKernel.cpp b/DDDigi/src/DigiKernel.cpp index 3c480bedcf8e09aed575f14e985556a7591c2c10..01a3b5a234b8eb09029f53b1619f5e7f19d2babe 100644 --- a/DDDigi/src/DigiKernel.cpp +++ b/DDDigi/src/DigiKernel.cpp @@ -27,6 +27,8 @@ #include <tbb/tbb.h> #endif +#include <TRandom.h> + // C/C++ include files #include <stdexcept> #include <algorithm> @@ -88,6 +90,10 @@ public: DigiActionSequence* eventAction { nullptr }; /// The main data output action sequence DigiActionSequence* outputAction { nullptr }; + + /// Random generator + TRandom* root_random; + std::shared_ptr<DigiRandomGenerator> random {}; /// TBB initializer (If TBB is used) void* tbbInit { nullptr }; /// Property: Output level @@ -151,6 +157,7 @@ public: int ev_num = kernel.internals->numEvents - todo; std::unique_ptr<DigiContext> context = std::make_unique<DigiContext>(this->kernel,std::make_unique<DigiEvent>(ev_num)); + context->set_random_generator(this->kernel.internals->random); kernel.executeEvent(std::move(context)); } } @@ -179,6 +186,9 @@ DigiKernel::DigiKernel(Detector& description_ref) internals->inputAction->setExecuteParallel(false); internals->eventAction->setExecuteParallel(false); internals->outputAction->setExecuteParallel(false); + internals->root_random = new TRandom(); + internals->random = std::make_shared<DigiRandomGenerator>(); + internals->random->engine = [this] { return this->internals->root_random->Uniform(1.0); }; InstanceCount::increment(this); } diff --git a/DDDigi/src/DigiSegmentSplitter.cpp b/DDDigi/src/DigiSegmentSplitter.cpp index f0cce33a9b094f7fb1b7cdc645db2578900579ec..ab2a1db77e6635712e52399031cb162e8477ea42 100644 --- a/DDDigi/src/DigiSegmentSplitter.cpp +++ b/DDDigi/src/DigiSegmentSplitter.cpp @@ -64,7 +64,8 @@ void DigiSegmentSplitter::initialize() { /// 1) Check if the workers were pre-configured if ( !m_workers.empty() ) { bool bad = false; - const auto& workers = m_workers.get(); + auto group = m_workers.get_group(); + const auto& workers = group.actors(); /// Create the processors: for( auto& p : m_splits ) { auto split_id = p.second.second; diff --git a/DDDigi/src/DigiStoreDump.cpp b/DDDigi/src/DigiStoreDump.cpp index f01ae514524a98f17e73503c6e0637561096ed6a..1b56b216a0e26bcf82576912dfd2bd9139649156 100644 --- a/DDDigi/src/DigiStoreDump.cpp +++ b/DDDigi/src/DigiStoreDump.cpp @@ -47,7 +47,7 @@ void dd4hep::digi::DigiStoreDump::dump(const std::string& tag, std::string str; std::vector<std::string> records; using detail::str_replace; - info("%s+---- %s segment: %ld entries", event.id(), tag.c_str(), data_segment.size()); + info("%s+--- %-12s segment: %ld entries", event.id(), tag.c_str(), data_segment.size()); std::lock_guard<std::mutex> lock(data_segment.lock); for ( const auto& e : data_segment ) { Key key {e.first}; @@ -59,22 +59,22 @@ void dd4hep::digi::DigiStoreDump::dump(const std::string& tag, typ = str_replace(str_replace(typ,"std::",""),"dd4hep::",""); typ = str_replace(str_replace(typ,"sim::",""),"digi::",""); if ( const auto* mapping = std::any_cast<DepositMapping>(&data) ) { - str = this->format("%s|---- %4X %08X %-32s: %6ld hits [%s]", + str = this->format("%s|---- %4X %08X %-32s: %6ld hits [%s]", event.id(), key.values.mask, key.values.item, nam.c_str(), mapping->size(), typ.c_str()); } else if ( const auto* vector = std::any_cast<DepositVector>(&data) ) { - str = this->format("%s|---- %4X %08X %-32s: %6ld hits [%s]", + str = this->format("%s|---- %4X %08X %-32s: %6ld hits [%s]", event.id(), key.values.mask, key.values.item, nam.c_str(), vector->size(), typ.c_str()); } else if ( const auto* parts = std::any_cast<ParticleMapping>(&data) ) { - str = this->format("%s|---- %4X %08X %-32s: %6ld particles [%s]", + str = this->format("%s|---- %4X %08X %-32s: %6ld particles [%s]", event.id(), key.values.mask, key.values.item, nam.c_str(), parts->size(), typ.c_str()); } else { - str = this->format("%s|---- %4X %08X %-32s: %s", + str = this->format("%s|---- %4X %08X %-32s: %s", event.id(), key.values.mask, key.values.item, nam.c_str(), typ.c_str()); } diff --git a/DDDigi/src/noise/DigiSignalProcessorSequence.cpp b/DDDigi/src/noise/DigiSignalProcessorSequence.cpp index f5d54c266ca8045aa204cf585f97ef3bf52a3f56..e31b10428fbd2d7b26c5f7aaf09e38a76989a6b7 100644 --- a/DDDigi/src/noise/DigiSignalProcessorSequence.cpp +++ b/DDDigi/src/noise/DigiSignalProcessorSequence.cpp @@ -55,7 +55,8 @@ void DigiSignalProcessorSequence::adopt(DigiSignalProcessor* action) { double DigiSignalProcessorSequence::operator()(DigiCellContext& context) const { CallData args { context, 0e0 }; double result = context.data.signal; - for ( const auto* p : m_actors.get() ) { + auto group = m_actors.get_group(); + for ( const auto* p : group.actors() ) { args.value = 0e0; p->execute(&args); result += args.value; diff --git a/examples/DDDigi/scripts/TestDepositCount.py b/examples/DDDigi/scripts/TestDepositCount.py new file mode 100644 index 0000000000000000000000000000000000000000..6aa866e76c0882e850b38da321dea5906a64e80b --- /dev/null +++ b/examples/DDDigi/scripts/TestDepositCount.py @@ -0,0 +1,32 @@ +# ========================================================================== +# AIDA Detector description implementation +# -------------------------------------------------------------------------- +# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +# All rights reserved. +# +# For the licensing terms see $DD4hepINSTALL/LICENSE. +# For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +# +# ========================================================================== +from __future__ import absolute_import + + +def run(): + import DigiTest + digi = DigiTest.Test(geometry=None) + + input = digi.input_action('DigiParallelActionSequence/Reader') + # ======================================================================================================== + digi.info('Created SIGNAL input') + signal = input.adopt_action('DigiSequentialActionSequence/Signal') + reader = signal.adopt_action('DigiROOTInput/SignalReader', mask=0x0, input=[digi.next_input()]) + sequence = signal.adopt_action('DigiContainerSequenceAction/Counter', + parallel=True, input_mask=0x0, input_segment='inputs') + count = digi.create_action('DigiCellMultiplicityCounter/CellCounter') + sequence.adopt_container_processor(count, digi.containers()) + # ======================================================================================================== + digi.run_checked(num_events=7, num_threads=7, parallel=3) + + +if __name__ == '__main__': + run() diff --git a/examples/DDDigi/scripts/TestHitProcessing.py b/examples/DDDigi/scripts/TestHitProcessing.py index ea61322503284434e4a9f86e143ee22e123774fb..b21d9faf4523710265aa749fd4f8b87293399da5 100644 --- a/examples/DDDigi/scripts/TestHitProcessing.py +++ b/examples/DDDigi/scripts/TestHitProcessing.py @@ -25,14 +25,12 @@ def run(): # ======================================================================================================== overlay = input.adopt_action('DigiSequentialActionSequence/Overlay-1') evtreader = overlay.adopt_action('DigiROOTInput/Read-1', mask=0x1, input=[digi.next_input()]) - hist_drop = overlay.adopt_action('DigiHitHistoryDrop/Drop-1', masks=[evtreader.mask]) - digi.check_creation([overlay, evtreader, hist_drop]) + digi.check_creation([overlay, evtreader]) digi.info('Created input.overlay-1') # ======================================================================================================== overlay = input.adopt_action('DigiSequentialActionSequence/Overlay-2') evtreader = overlay.adopt_action('DigiROOTInput/Read-2', mask=0x2, input=[digi.next_input()]) - hist_drop = overlay.adopt_action('DigiHitHistoryDrop/Drop-2', masks=[evtreader.mask]) - digi.check_creation([overlay, evtreader, hist_drop]) + digi.check_creation([overlay, evtreader]) digi.info('Created input.overlay-2') # ======================================================================================================== event = digi.event_action('DigiSequentialActionSequence/EventAction') @@ -43,17 +41,21 @@ def run(): output_segment='deposits', erase_combined=False) combine.erase_combined = True - dump = event.adopt_action('DigiStoreDump/StoreDump') - proc = event.adopt_action('DigiContainerSequenceAction/HitP1', parallel=True, input_mask=0xFEED, input_segment='deposits') + proc = event.adopt_action('DigiContainerSequenceAction/HitP1', + parallel=True, + input_mask=0xFEED, + input_segment='deposits') count = digi.create_action('DigiCellMultiplicityCounter/CellCounter') proc.adopt_container_processor(count, digi.containers()) - proc = event.adopt_action('DigiContainerSequenceAction/HitP2', parallel=True, + proc = event.adopt_action('DigiContainerSequenceAction/HitP2', + parallel=True, input_mask=0xFEED, input_segment='deposits', - output_mask = 0x0, + output_mask=0x0, output_segment='output') - count = digi.create_action('DigiDepositMapCreator/CellCreator') + count = digi.create_action('DigiDepositWeightedPosition/CellCreator') proc.adopt_container_processor(count, digi.containers()) + dump = event.adopt_action('DigiStoreDump/StoreDump') digi.check_creation([combine, dump, proc]) digi.info('Created event.dump') diff --git a/examples/DDDigi/scripts/TestIPMove.py b/examples/DDDigi/scripts/TestIPMove.py new file mode 100644 index 0000000000000000000000000000000000000000..f5435bb3626fd1f8b95b56d9cad4da7341e6aa27 --- /dev/null +++ b/examples/DDDigi/scripts/TestIPMove.py @@ -0,0 +1,39 @@ +# ========================================================================== +# AIDA Detector description implementation +# -------------------------------------------------------------------------- +# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +# All rights reserved. +# +# For the licensing terms see $DD4hepINSTALL/LICENSE. +# For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +# +# ========================================================================== +from __future__ import absolute_import + + +def run(): + import DigiTest + digi = DigiTest.Test(geometry=None) + + input = digi.input_action('DigiParallelActionSequence/READER') + # ======================================================================================================== + digi.info('Created SIGNAL input') + signal = input.adopt_action('DigiSequentialActionSequence/Signal') + reader = signal.adopt_action('DigiROOTInput/SignalReader', mask=0x0, input=[digi.next_input()]) + set_ip = signal.adopt_action('DigiIPCreate/SignalIP') + set_ip.offset_ip = [1, 2, 3] + set_ip.sigma_ip = [.5, .5, 3.0] + move_seq = signal.adopt_action('DigiContainerSequenceAction/MoveSignal', + parallel=True, input_mask=0x0, input_segment='inputs') + mover = digi.create_action('DigiIPMover/MoveIPSignal') + mover.ip_property = 'interaction_point' + mover.ip_creator = set_ip.get() + conts = [c for c in digi.containers()] + conts.append('MCParticles') + move_seq.adopt_container_processor(mover, conts) + # ======================================================================================================== + digi.run_checked(num_events=7, num_threads=7, parallel=3) + + +if __name__ == '__main__': + run() diff --git a/examples/DDDigi/scripts/TestProperties.py b/examples/DDDigi/scripts/TestProperties.py new file mode 100644 index 0000000000000000000000000000000000000000..be4d294d357cbfc6ae1fa6887cc66f8d0f602207 --- /dev/null +++ b/examples/DDDigi/scripts/TestProperties.py @@ -0,0 +1,92 @@ +# ========================================================================== +# AIDA Detector description implementation +# -------------------------------------------------------------------------- +# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +# All rights reserved. +# +# For the licensing terms see $DD4hepINSTALL/LICENSE. +# For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +# +# ========================================================================== +from __future__ import absolute_import + + +def yes_no(val): + if val: + return "YES" + return "NO " + +def run(): + import DigiTest + digi = DigiTest.Test(geometry=None) + input = digi.input_action('DigiParallelActionSequence/Test') + + input.add_property('property_int', 1) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_int')),)) + print('property: property_int = %s'%(str(input.property_int),)) + input.property_int = 123456 + print('property: property_int = %s'%(str(input.property_int),)) + + input.add_vector_property('property_vector_int', [1,2,3]) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_vector_int')),)) + print('property: property_vector_int = %s'%(str(input.property_vector_int),)) + input.property_vector_int = [1,2,3,4,5,6,7,8,9,0] + print('property: property_vector_int = %s'%(str(input.property_vector_int),)) + + input.add_list_property('property_list_int', [1,2,3]) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_list_int')),)) + print('property: property_list_int = %s'%(str(input.property_list_int),)) + input.property_list_int = [1,2,3,4,5,6,7,8,9,0] + print('property: property_list_int = %s'%(str(input.property_list_int),)) + + input.add_set_property('property_set_int', [1,2,3]) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_set_int')),)) + print('property: property_set_int = %s'%(str(input.property_set_int),)) + input.property_set_int = [1,2,3,4,5,6,7,8,9,0] + print('property: property_set_int = %s'%(str(input.property_set_int),)) + + input.add_property('property_double', 1.0) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_double')),)) + print('property: property_double = %s'%(str(input.property_double),)) + input.property_double = 123456.7 + print('property: property_double = %s'%(str(input.property_double),)) + + input.add_vector_property('property_vector_double', [1.1,2,3]) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_vector_double')),)) + print('property: property_vector_double = %s'%(str(input.property_vector_double),)) + input.property_vector_double = [1.5,2,3,4,5,6,7,8,9,0] + print('property: property_vector_double = %s'%(str(input.property_vector_double),)) + + input.add_list_property('property_list_double', [1.1,2,3]) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_list_double')),)) + print('property: property_list_double = %s'%(str(input.property_list_double),)) + input.property_list_double = [1.5,2,3,4,5,6,7,8,9,0] + print('property: property_list_double = %s'%(str(input.property_list_double),)) + + input.add_set_property('property_set_double', [1.1,2,3]) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_set_double')),)) + print('property: property_set_double = %s'%(str(input.property_set_double),)) + input.property_set_double = [1.5,2,3,4,5,6,7,8,9,0] + print('property: property_set_double = %s'%(str(input.property_set_double),)) + + input.add_property('property_string', "string_1") + print('property: has_property = %s'%(yes_no(input.hasProperty('property_string')),)) + print('property: property_string = %s'%(input.property_string,)) + input.property_string = "string_1123456" + print('property: property_string = %s'%(input.property_string,)) + + input.add_vector_property('property_vector_string', ["string1","string2","string3"]) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_vector_string')),)) + print('property: property_vector_string = %s'%(input.property_vector_string,)) + input.property_vector_string = ["string1","string2","string3","string4","string5","string6"] + print('property: property_vector_string = %s'%(input.property_vector_string,)) + + input.add_position_property('property_position', (1.,2.,3.)) + print('property: has_property = %s'%(yes_no(input.hasProperty('property_position')),)) + print('property: property_position = %s'%(input.property_position,)) + input.property_position = (111.1, 222.2, 333.3) + print('property: property_position = %s'%(input.property_position,)) + + +if __name__ == '__main__': + run() diff --git a/examples/DDDigi/scripts/TestResegmentation.py b/examples/DDDigi/scripts/TestResegmentation.py new file mode 100644 index 0000000000000000000000000000000000000000..ed42aa1ee9369471072d756a95fa16f934dce973 --- /dev/null +++ b/examples/DDDigi/scripts/TestResegmentation.py @@ -0,0 +1,47 @@ +# ========================================================================== +# AIDA Detector description implementation +# -------------------------------------------------------------------------- +# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +# All rights reserved. +# +# For the licensing terms see $DD4hepINSTALL/LICENSE. +# For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +# +# ========================================================================== +from __future__ import absolute_import + + +def run(): + import DigiTest + digi = DigiTest.Test(geometry=None) + digi.load_geo() + input = digi.input_action('DigiParallelActionSequence/READER') + # ======================================================================== + digi.info('Created SIGNAL input') + signal = input.adopt_action('DigiROOTInput/SignalReader', mask=0x0, input=[digi.next_input()]) + digi.check_creation([signal]) + # ======================================================================== + event = digi.event_action('DigiSequentialActionSequence/EventAction') + seq = event.adopt_action('DigiContainerSequenceAction/ResegmentSeq', + parallel=True, + input_mask=0x0, input_segment='inputs', + output_mask=0xFEED, output_segment='outputs') + resegment = digi.create_action('DigiResegment/Resegment') + resegment.detector = 'EcalBarrel' + resegment.readout = 'NewEcalBarrelHits' + resegment.descriptor = """ + <readout name="NewEcalBarrelHits"> + <segmentation type="CartesianGridXY" grid_size_x="10" grid_size_y="10" /> + <id>system:8,barrel:3,module:4,layer:6,slice:5,x:32:-16,y:-16</id> + </readout> + """ + seq.adopt_container_processor(resegment,'EcalBarrelHits') + dump = event.adopt_action('DigiStoreDump/StoreDump') + + digi.info('Created event.dump') + # ======================================================================== + digi.run_checked(num_events=3, num_threads=5, parallel=3) + + +if __name__ == '__main__': + run() diff --git a/examples/DDDigi/scripts/TestSpillover.py b/examples/DDDigi/scripts/TestSpillover.py index e3ef4562d806ede03f2fd1dbeb5a6b8447383775..6745adb40ce62ee76148881cd480b1580fa9cf45 100644 --- a/examples/DDDigi/scripts/TestSpillover.py +++ b/examples/DDDigi/scripts/TestSpillover.py @@ -28,60 +28,62 @@ def run(): spillover = input.adopt_action('DigiSequentialActionSequence/Spillover-25') evtreader = spillover.adopt_action('DigiROOTInput/Reader-25ns', mask=0x1, input=[digi.next_input()]) attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att-25ns', - t0=-25 * ns, + t0=-25 * ns, signal_decay='exponential', processor_type='DigiAttenuator', - mask=evtreader.mask, + input_mask=evtreader.mask, + input_segment='inputs', containers=attenuation) hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop-25ns', masks=[evtreader.mask]) digi.check_creation([spillover, evtreader, attenuate, hist_drop]) - digi.info('Created input.spillover25') + digi.info('Created input.spillover-25') # ======================================================================================================== spillover = input.adopt_action('DigiSequentialActionSequence/Spillover-50') evtreader = spillover.adopt_action('DigiROOTInput/Reader-50ns', mask=0x2, input=[digi.next_input()]) attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att-50ns', - t0=-50 * ns, mask=evtreader.mask, containers=attenuation) + t0=-50 * ns, input_mask=evtreader.mask, containers=attenuation) hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop-50ns', masks=[evtreader.mask]) digi.check_creation([spillover, evtreader, attenuate, hist_drop]) - digi.info('Created input.spillover50') + digi.info('Created input.spillover-50') # ======================================================================================================== spillover = input.adopt_action('DigiSequentialActionSequence/Spillover-75') evtreader = spillover.adopt_action('DigiROOTInput/Reader-75ns', mask=0x3, input=[digi.next_input()]) attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att-75ns', - t0=-75 * ns, mask=evtreader.mask, containers=attenuation) + t0=-75 * ns, input_mask=evtreader.mask, containers=attenuation) hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop-75ns', masks=[evtreader.mask]) digi.check_creation([spillover, evtreader, attenuate, hist_drop]) - digi.info('Created input.spillover75') + digi.info('Created input.spillover-75') # ======================================================================================================== digi.info('Creating spillover sequence for LATER bunch crossings.....') # ======================================================================================================== spillover = input.adopt_action('DigiSequentialActionSequence/Spillover+25') evtreader = spillover.adopt_action('DigiROOTInput/Reader+25ns', mask=0x4, input=[digi.next_input()]) attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att+25ns', - t0=25 * ns, mask=evtreader.mask, containers=attenuation) + t0=25 * ns, input_mask=evtreader.mask, containers=attenuation) hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop+25ns', masks=[evtreader.mask]) digi.check_creation([spillover, evtreader, attenuate, hist_drop]) - digi.info('Created input.spillover25') + digi.info('Created input.spillover+25') # ======================================================================================================== spillover = input.adopt_action('DigiSequentialActionSequence/Spillover+50') evtreader = spillover.adopt_action('DigiROOTInput/Reader+50ns', mask=0x5, input=[digi.next_input()]) attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att+50ns', - t0=50 * ns, mask=evtreader.mask, containers=attenuation) + t0=50 * ns, input_mask=evtreader.mask, containers=attenuation) hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop_50ns', masks=[evtreader.mask]) digi.check_creation([spillover, evtreader, attenuate, hist_drop]) - digi.info('Created input.spillover50') + digi.info('Created input.spillover+50') # ======================================================================================================== spillover = input.adopt_action('DigiSequentialActionSequence/Spillover+75') evtreader = spillover.adopt_action('DigiROOTInput/Reader+75ns', mask=0x6, input=[digi.next_input()]) attenuate = spillover.adopt_action('DigiAttenuatorSequence/Att+75ns', - t0=75 * ns, mask=evtreader.mask, containers=attenuation) + t0=75 * ns, input_mask=evtreader.mask, containers=attenuation) hist_drop = spillover.adopt_action('DigiHitHistoryDrop/Drop+75ns', masks=[evtreader.mask]) digi.check_creation([spillover, evtreader, attenuate, hist_drop]) - digi.info('Created input.spillover75') + digi.info('Created input.spillover+75') # ======================================================================================================== event = digi.event_action('DigiSequentialActionSequence/EventAction') combine = event.adopt_action('DigiContainerCombine/Combine', input_masks=[0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6], + input_segment='inputs', output_mask=0xFEED, output_segment='deposits') combine.erase_combined = True # Not thread-safe! only do in SequentialActionSequence