From 7ed9c49b72696edc5ed01da7dcb876782258f2b9 Mon Sep 17 00:00:00 2001 From: Markus Frank <markus.frank@cern.ch> Date: Thu, 3 Mar 2016 14:10:32 +0000 Subject: [PATCH] Improved property handling. See release notes. --- DDCond/include/DDCond/ConditionsIOVPool.h | 73 ++++++++ DDCond/include/DDCond/ConditionsInterna.h | 53 +----- DDCond/include/DDCond/ConditionsPool.h | 25 +-- DDCond/src/ConditionsExample.cpp | 107 ++++++++--- DDCond/src/ConditionsIOVPool.cpp | 111 ++++++++++++ DDCond/src/ConditionsInterna.cpp | 169 +++++------------- DDCond/src/ConditionsLinearPool.cpp | 2 +- DDCond/src/ConditionsPool.cpp | 3 - DDCond/src/ConditionsTest.cpp | 116 ++++++------ DDCond/src/ConditionsTest.h | 9 +- DDCore/include/DD4hep/Conditions.h | 24 ++- DDCore/include/DD4hep/Handle.h | 8 +- DDCore/include/DD4hep/Handle.inl | 14 +- DDCore/include/DD4hep/Parsers.h | 32 ++-- DDCore/include/DD4hep/Primitives.h | 79 ++++++++ DDCore/include/DD4hep/ToStream.h | 12 ++ .../include/DD4hep/objects/BasicGrammar_inl.h | 80 +++++++-- .../DD4hep/objects/ConditionsInterna.h | 9 +- DDCore/src/BasicGrammarTypes.cpp | 21 +-- DDCore/src/Conditions.cpp | 12 +- DDCore/src/ConditionsInterna.cpp | 4 +- DDCore/src/ConditonsTypes.cpp | 16 +- DDCore/src/Primitives.cpp | 63 ++++++- DDCore/src/parsers/GrammarsV2.h | 21 ++- DDCore/src/parsers/ParsersObjects.cpp | 141 --------------- .../parsers/ParsersObjects_PxPyPzEVector.cpp | 43 +++++ .../src/parsers/ParsersObjects_XYZPoint.cpp | 41 +++++ .../src/parsers/ParsersObjects_XYZVector.cpp | 54 ++++++ .../src/parsers/ParsersStandardListCommon.h | 54 +++++- .../src/parsers/ParsersStandardList_bool.cpp | 13 ++ .../src/parsers/ParsersStandardList_char.cpp | 13 ++ .../parsers/ParsersStandardList_double.cpp | 13 ++ .../src/parsers/ParsersStandardList_float.cpp | 13 ++ .../src/parsers/ParsersStandardList_int.cpp | 13 ++ .../src/parsers/ParsersStandardList_long.cpp | 13 ++ ...cpp => ParsersStandardList_longdouble.cpp} | 5 +- .../parsers/ParsersStandardList_longlong.cpp | 13 ++ .../src/parsers/ParsersStandardList_short.cpp | 13 ++ .../ParsersStandardList_signedchar.cpp | 13 ++ ...ist1.cpp => ParsersStandardList_uchar.cpp} | 5 +- .../src/parsers/ParsersStandardList_uint.cpp | 13 ++ .../src/parsers/ParsersStandardList_ulong.cpp | 13 ++ ....cpp => ParsersStandardList_ulonglong.cpp} | 5 +- ...st2.cpp => ParsersStandardList_ushort.cpp} | 5 +- DDCore/src/parsers/ParsersStandardMisc1.cpp | 4 - DDCore/src/parsers/ParsersStandardMisc2.cpp | 12 -- DDCore/src/parsers/ParsersStandardMisc3.cpp | 12 -- DDCore/src/parsers/ParsersStandardMisc4.cpp | 4 - DDCore/src/parsers/ParsersStandard_string.cpp | 13 ++ DDG4/examples/SiDSim.py | 2 + DDG4/include/DDG4/Geant4IsotropeGenerator.h | 12 +- DDG4/python/DDG4.py | 2 +- DDG4/src/Geant4IsotropeGenerator.cpp | 86 ++++++++- doc/release.notes | 8 + 54 files changed, 1155 insertions(+), 559 deletions(-) create mode 100644 DDCond/include/DDCond/ConditionsIOVPool.h create mode 100644 DDCond/src/ConditionsIOVPool.cpp delete mode 100644 DDCore/src/parsers/ParsersObjects.cpp create mode 100644 DDCore/src/parsers/ParsersObjects_PxPyPzEVector.cpp create mode 100644 DDCore/src/parsers/ParsersObjects_XYZPoint.cpp create mode 100644 DDCore/src/parsers/ParsersObjects_XYZVector.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_bool.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_char.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_double.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_float.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_int.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_long.cpp rename DDCore/src/parsers/{ParsersStandardList4.cpp => ParsersStandardList_longdouble.cpp} (85%) create mode 100644 DDCore/src/parsers/ParsersStandardList_longlong.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_short.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_signedchar.cpp rename DDCore/src/parsers/{ParsersStandardList1.cpp => ParsersStandardList_uchar.cpp} (85%) create mode 100644 DDCore/src/parsers/ParsersStandardList_uint.cpp create mode 100644 DDCore/src/parsers/ParsersStandardList_ulong.cpp rename DDCore/src/parsers/{ParsersStandardList3.cpp => ParsersStandardList_ulonglong.cpp} (84%) rename DDCore/src/parsers/{ParsersStandardList2.cpp => ParsersStandardList_ushort.cpp} (85%) create mode 100644 DDCore/src/parsers/ParsersStandard_string.cpp diff --git a/DDCond/include/DDCond/ConditionsIOVPool.h b/DDCond/include/DDCond/ConditionsIOVPool.h new file mode 100644 index 000000000..764b56607 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsIOVPool.h @@ -0,0 +1,73 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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 +// +//========================================================================== +#ifndef DDCOND_CONDITIONSIOVPOOL_H +#define DDCOND_CONDITIONSIOVPOOL_H + +// Framework include files +#include "DDCond/ConditionsPool.h" + +// C/C++ include files +#include <map> + +/// Namespace for the AIDA detector description toolkit +namespace DD4hep { + + /// Namespace for the geometry part of the AIDA detector description toolkit + namespace Conditions { + + /// Forward declarations + class ConditionsDataLoader; + + /// Pool of conditions satisfying one IOV type (epoch, run, fill, etc) + /** + * Purely internal class to the conditions manager implementation. + * Not at all to be accessed by clients! + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CONDITIONS + */ + class ConditionsIOVPool { + public: + typedef ConditionsPool* Entry; + typedef std::map<std::pair<int,int>, Entry > Entries; + Entries entries; + public: + /// Default constructor + ConditionsIOVPool(); + /// Default destructor + virtual ~ConditionsIOVPool(); + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + void __find(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& result); + /// Retrieve a condition set given a Detector Element and the conditions name according to their validity + void __find_range(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& result); + /// Select all ACTIVE conditions, which do no longer match the IOV requirement + void __select_expired(const IOV& required_validity, + RangeConditions& result); + void __update_expired(ConditionsDataLoader& loader, + ConditionsPool& pool, + RangeConditions& expired, + const IOV& required_validity); + }; + + } /* End namespace Conditions */ +} /* End namespace DD4hep */ + +#endif /* DDCOND_CONDITIONSIOVPOOL_H */ diff --git a/DDCond/include/DDCond/ConditionsInterna.h b/DDCond/include/DDCond/ConditionsInterna.h index 1abb02878..6ca9ab592 100644 --- a/DDCond/include/DDCond/ConditionsInterna.h +++ b/DDCond/include/DDCond/ConditionsInterna.h @@ -14,11 +14,12 @@ #ifndef DDCOND_CONDITIONSINTERNA_H #define DDCOND_CONDITIONSINTERNA_H -// Framework include files +// Framework include files% #include "DD4hep/Mutex.h" #include "DD4hep/Memory.h" #include "DD4hep/Conditions.h" #include "DDCond/ConditionsPool.h" +#include "DDCond/ConditionsIOVPool.h" #include "DDCond/ConditionsDataLoader.h" // C/C++ include files @@ -32,13 +33,9 @@ namespace DD4hep { namespace Conditions { class Entry; - class IOVPool; class ConditionsPool; + class ConditionsIOVPool; class ConditionsDataLoader; - typedef std::pair<RangeConditions,bool> RangeStatus; - - using Geometry::LCDD; - using Geometry::DetElement; /// Conditions internal namespace declaration /** Internally defined datastructures are not presented to the @@ -65,7 +62,7 @@ namespace DD4hep { typedef dd4hep_ptr<ConditionsDataLoader> Loader; typedef std::vector<IOVType> IOVTypes; - typedef std::vector<IOVPool*> TypedConditionPool; + typedef std::vector<ConditionsIOVPool*> TypedConditionPool; typedef std::map<IOV::Key, ReplacementPool*> ReplacementCache; typedef std::vector<ReplacementPool*> FreePools; @@ -82,10 +79,11 @@ namespace DD4hep { /// Property: Conditions loader type (default: "multi" -> DD4hep_Conditions_multi_Loader) std::string m_loaderType; - /// Reference to main detector description object LCDD& m_lcdd; + /// Collection of IOV types managed IOVTypes m_iovTypes; + /// Managed pool of typed conditions idexed by IOV-type and IOV key TypedConditionPool m_pool; /// Lock to protect the update/delayed conditions pool dd4hep_mutex_t m_updateLock; @@ -200,45 +198,6 @@ namespace DD4hep { const IOV& req_range_validity); }; } /* End namespace Interna */ - - /// Pool of conditions satisfying one IOV type (epoch, run, fill, etc) - /** - * Purely internal class to the conditions manager implementation. - * Not at all to be accessed by clients! - * - * \author M.Frank - * \version 1.0 - * \ingroup DD4HEP_CONDITIONS - */ - class IOVPool { - public: - typedef ConditionsPool* Entry; - typedef std::map<std::pair<int,int>, Entry > Entries; - Entries entries; - public: - /// Default constructor - IOVPool(); - /// Default destructor - virtual ~IOVPool(); - /// Retrieve a condition set given a Detector Element and the conditions name according to their validity - void __find(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& result); - /// Retrieve a condition set given a Detector Element and the conditions name according to their validity - void __find_range(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& result); - /// Select all ACTIVE conditions, which do no longer match the IOV requirement - void __select_expired(const IOV& required_validity, - RangeConditions& result); - void __update_expired(Interna::ConditionsManagerObject* caller, - ConditionsPool* pool, - RangeConditions& expired, - const IOV& required_validity); - }; - } /* End namespace Conditions */ } /* End namespace DD4hep */ diff --git a/DDCond/include/DDCond/ConditionsPool.h b/DDCond/include/DDCond/ConditionsPool.h index e65a8cd82..ab2e3ac3d 100644 --- a/DDCond/include/DDCond/ConditionsPool.h +++ b/DDCond/include/DDCond/ConditionsPool.h @@ -86,13 +86,9 @@ namespace DD4hep { /// Full cleanup of all managed conditions. virtual void clear() = 0; /// Check if a condition exists in the pool - virtual Condition exists(DetElement, const std::string&) const { - return Condition(); - } + virtual Condition exists(DetElement, const std::string&) const = 0; /// Check if a condition exists in the pool - virtual Condition exists(Condition) const { - return Condition(); - } + virtual Condition exists(Condition) const = 0; /// Select the conditions matching the DetElement and the conditions name virtual void select(DetElement det, const std::string& cond_name, RangeConditions& result) = 0; /// Select all conditions contained @@ -103,8 +99,6 @@ namespace DD4hep { /// Interface for conditions pool optimized to host conditions updates. /** - * Common function for all pools..... - * * \author M.Frank * \version 1.0 */ @@ -123,11 +117,7 @@ namespace DD4hep { /// Adopt all entries sorted by IOV. Entries will be removed from the pool virtual void popEntries(UpdateEntries& entries) = 0; /// Register a new condition to this pool - virtual void insert(Condition cond) = 0; - /// Register a new condition to this pool. May overload for performance reasons. - virtual void insert(RangeConditions& cond) = 0; - /// Register a new condition to this pool - virtual Condition insert(ConditionsPool* pool, Entry* cond) = 0; + virtual Condition insertEntry(ConditionsPool* pool, Entry* cond) = 0; /// Select the conditions matching the DetElement and the conditions name virtual void select_range(DetElement det, const std::string& cond_name, @@ -135,16 +125,17 @@ namespace DD4hep { RangeConditions& result) = 0; }; + /// Interface for conditions pool optimized to host conditions updates. + /** + * \author M.Frank + * \version 1.0 + */ class ReplacementPool : public ConditionsPool { public: /// Default constructor ReplacementPool(); /// Default destructor. virtual ~ReplacementPool(); - /// Register a new condition to this pool - virtual void insert(Condition cond) = 0; - /// Register a new condition to this pool. May overload for performance reasons. - virtual void insert(RangeConditions& cond) = 0; /// Pop conditions. May overloade for performance reasons! virtual void popEntries(RangeConditions& entries) = 0; }; diff --git a/DDCond/src/ConditionsExample.cpp b/DDCond/src/ConditionsExample.cpp index b9cab82ca..9b3cc3482 100644 --- a/DDCond/src/ConditionsExample.cpp +++ b/DDCond/src/ConditionsExample.cpp @@ -25,47 +25,58 @@ using Geometry::DetElement; namespace { - void print_tpc_discrete_conditions(Test::TestEnv& env, int epoch_min, int epoch_max, int run_min, int run_max) { - IOV iov_epoch(env.epoch), iov_run(env.run); - iov_epoch.keyData.first = epoch_min; - iov_epoch.keyData.second = epoch_max; - iov_run.keyData.first = run_min; - iov_run.keyData.second = run_max; - - env.manager.prepare(iov_run); - env.manager.enable(iov_run); - env.manager.prepare(iov_epoch); - env.manager.enable(iov_epoch); - + void print_tpc_epoch_conditions(Test::TestEnv& env, const IOV& iov_epoch, bool check = true) { Condition cond = env.manager.get(env.detector,"AmbientTemperature",iov_epoch); Test::print_condition<void>(cond); cond = env.detector.condition("AmbientTemperature",iov_epoch); - Test::check_discrete_condition(cond, iov_epoch); + if ( check ) Test::check_discrete_condition(cond, iov_epoch); Test::print_condition<void>(cond); cond = env.detector.condition("ExternalPressure",iov_epoch); - Test::check_discrete_condition(cond, iov_epoch); + if ( check ) Test::check_discrete_condition(cond, iov_epoch); Test::print_condition<void>(cond); cond = env.detector.condition("SomeMultiParams",iov_epoch); - Test::check_discrete_condition(cond, iov_epoch); + if ( check ) Test::check_discrete_condition(cond, iov_epoch); Test::print_condition<void>(cond); - printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - printout(INFO,"Example","SUCCESS: +++ Conditions access OK for iov:%s!",iov_epoch.str().c_str()); - printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - - cond = env.detector.condition("alignment",iov_run); - Test::check_discrete_condition(cond, iov_run); + cond->value = "[5,6,7,8,9,10,11,12,13,14]"; + cond.rebind(); + Test::print_condition<void>(cond); + } + void print_tpc_run_conditions(Test::TestEnv& env, const IOV& iov_run, bool check = true) { + Condition cond = env.detector.condition("alignment",iov_run); + if ( check ) Test::check_discrete_condition(cond, iov_run); Test::print_condition<void>(cond); cond = env.detector.condition("TPC_A_align",iov_run); - Test::check_discrete_condition(cond, iov_run); + if ( check ) Test::check_discrete_condition(cond, iov_run); Test::print_condition<void>(cond); cond = env.daughter("TPC_SideA").condition("alignment",iov_run); - Test::check_discrete_condition(cond, iov_run); + if ( check ) Test::check_discrete_condition(cond, iov_run); Test::print_condition<void>(cond); + } + void print_tpc_discrete_conditions(Test::TestEnv& env, const IOV& iov_epoch, const IOV& iov_run) { + print_tpc_epoch_conditions(env, iov_epoch); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example","SUCCESS: +++ Conditions access OK for iov:%s!",iov_epoch.str().c_str()); + printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + print_tpc_run_conditions(env, iov_run); printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); printout(INFO,"Example","SUCCESS: +++ DISCRETE Conditions access OK for iov:%s!",iov_run.str().c_str()); printout(INFO,"Example","SUCCESS: +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); } + void print_tpc_discrete_conditions(Test::TestEnv& env, int epoch_min, int epoch_max, int run_min, int run_max) { + IOV iov_epoch(env.epoch), iov_run(env.run); + iov_epoch.keyData.first = epoch_min; + iov_epoch.keyData.second = epoch_max; + iov_run.keyData.first = run_min; + iov_run.keyData.second = run_max; + + env.manager.prepare(iov_run); + env.manager.enable(iov_run); + env.manager.prepare(iov_epoch); + env.manager.enable(iov_epoch); + print_tpc_discrete_conditions(env, iov_epoch, iov_run); + } + void print_tpc_discrete_conditions(Test::TestEnv& env) { print_tpc_discrete_conditions(env, 1396887257, 1396887257, 563543, 563543); print_tpc_discrete_conditions(env, 1396887257, 1396887257, 234567, 234567); @@ -93,7 +104,7 @@ namespace { int example1(LCDD& lcdd, int, char** ) { printout(INFO,"Example1","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - printout(INFO,"Example1","+++ Executing Conditions example No. 1: Test conditions access"); + printout(INFO,"Example1","+++ Executing Conditions example No. 1: Test conditions access. "); printout(INFO,"Example1","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); Test::TestEnv env(lcdd, "TPC"); @@ -114,7 +125,7 @@ namespace { int example2(LCDD& lcdd, int argc, char** argv) { printout(INFO,"Example2","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - printout(INFO,"Example2","+++ Executing Conditions example No. 2: Dump conditions tree"); + printout(INFO,"Example2","+++ Executing Conditions example No. 2: Dump conditions tree. "); printout(INFO,"Example2","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); DetElement det = lcdd.world(); string args = ""; @@ -124,7 +135,48 @@ namespace { return 1; } - struct Callee { + int example3(LCDD& lcdd, int, char** ) { + printout(INFO,"Example1","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + printout(INFO,"Example1","+++ Executing Conditions example No. 3: Conditions register/enable"); + printout(INFO,"Example1","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + Test::TestEnv env(lcdd, "TPC"); + + env.add_xml_data_source("/examples/Conditions/xml/TPC.xml"); + env.add_xml_data_source("/examples/Conditions/xml/TPC_run_563543.xml"); + env.add_xml_data_source("/examples/Conditions/xml/TPC_run_234567.xml"); + env.add_xml_data_source("/examples/Conditions/xml/TPC_run_filler.xml"); + env.add_xml_data_source("/examples/Conditions/xml/TPC_run_123456.xml"); + + + IOV iov_epoch(env.epoch), iov_run(env.run); + iov_epoch.keyData.first = 1396887257; + iov_epoch.keyData.second = 1396887257; + iov_run.keyData.first = 563543; + iov_run.keyData.second = 563543; + + env.manager.prepare(iov_run); + env.manager.enable(iov_run); + env.manager.prepare(iov_epoch); + env.manager.enable(iov_epoch); + print_tpc_epoch_conditions(env, iov_epoch); + print_tpc_run_conditions(env, iov_run, true); + printout(INFO,"Example1","==================================================================="); + + printout(INFO,"Example1","==================================================================="); + iov_run.keyData.first = iov_run.keyData.second = 123456; + env.manager.prepare(iov_run); + iov_run.keyData.first = iov_run.keyData.second = 563543; + print_tpc_run_conditions(env, iov_run, false); + printout(INFO,"Example1","==================================================================="); + + printout(INFO,"Example1","==================================================================="); + iov_run.keyData.first = iov_run.keyData.second = 123456; + env.manager.enable(iov_run); + print_tpc_run_conditions(env, iov_run, true); + return 1; + } + + struct Callee { int m_param; Callee() : m_param(0) {} void call(unsigned long tags, DetElement& det, void* param) { @@ -147,7 +199,7 @@ namespace { int DD4hep_CallbackInstallTest(LCDD& lcdd, int argc, char** argv) { printout(INFO,"Example3","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - printout(INFO,"Example3","+++ Executing DD4hepCallbackInstallTest: Install user callbacks"); + printout(INFO,"Example3","+++ Executing DD4hepCallbackInstallTest: Install user callbacks. "); printout(INFO,"Example3","+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); string args = ""; for(int i=0; i<argc; ++i) { args += argv[i], args += " "; }; @@ -160,5 +212,6 @@ namespace { DECLARE_APPLY(DD4hepConditionsAccessTest,example1) +DECLARE_APPLY(DD4hepExample3,example3) DECLARE_APPLY(DD4hepConditionsTreeDump,example2) DECLARE_APPLY(DD4hepCallbackInstallTest,DD4hep_CallbackInstallTest) diff --git a/DDCond/src/ConditionsIOVPool.cpp b/DDCond/src/ConditionsIOVPool.cpp new file mode 100644 index 000000000..b732e3924 --- /dev/null +++ b/DDCond/src/ConditionsIOVPool.cpp @@ -0,0 +1,111 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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/Printout.h" +#include "DD4hep/InstanceCount.h" +#include "DDCond/ConditionsIOVPool.h" +#include "DDCond/ConditionsDataLoader.h" + +using namespace DD4hep; +using namespace DD4hep::Conditions; + +/// Default constructor +ConditionsIOVPool::ConditionsIOVPool() { + InstanceCount::increment(this); +} + +/// Default destructor +ConditionsIOVPool::~ConditionsIOVPool() { + InstanceCount::decrement(this); +} + +void ConditionsIOVPool::__find(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& result) +{ + if ( !entries.empty() ) { + const IOV::Key req_key = req_validity.key(); // 8 bytes => better copy! + for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + if ( IOV::key_contains_range((*i).first, req_key) ) { + (*i).second->select(detector, condition_name, result); + } + } + } +} + +void ConditionsIOVPool::__find_range(DetElement detector, + const std::string& condition_name, + const IOV& req_validity, + RangeConditions& result) +{ + const IOV::Key range = req_validity.key(); + for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + const IOV::Key& key = (*i).first; + if ( IOV::key_is_contained(key,range) ) + // IOV test contained in key. Take it! + (*i).second->select(detector, condition_name, result); + else if ( IOV::key_overlaps_lower_end(key,range) ) + // IOV overlap on test on the lower end of key + (*i).second->select(detector, condition_name, result); + else if ( IOV::key_overlaps_higher_end(key,range) ) + // IOV overlap of test on the higher end of key + (*i).second->select(detector, condition_name, result); + } +} + +/// Select all ACTIVE conditions, which do no longer match the IOV requirement +void ConditionsIOVPool::__select_expired(const IOV& required_validity, RangeConditions& result) { + if ( !entries.empty() ) { + const IOV::Key req_key = required_validity.key(); // 8 bytes => better copy! + for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + ConditionsPool* pool = (*i).second; + if ( !IOV::key_contains_range((*i).first, req_key) ) { + if ( pool->age_value == ConditionsPool::AGE_NONE ) { + // Now check the content: + pool->select_used(result); + } + ++pool->age_value; + continue; + } + pool->age_value = 0; + } + } +} + +/// Select all ACTIVE conditions, which do no longer match the IOV requirement +void ConditionsIOVPool::__update_expired(ConditionsDataLoader& loader, + ConditionsPool& new_pool, + RangeConditions& updates, + const IOV& required_validity) { + + RangeConditions upda; + for(RangeConditions::const_iterator i=updates.begin(); i!=updates.end(); ++i) { + Condition::Object* condition = (*i).ptr(); + Condition c = new_pool.exists(condition); + if ( c.isValid() ) { + upda.push_back(c); + continue; + } + size_t items = loader.load(condition->detector,condition->name,required_validity,upda); + if ( items < 1 ) { + // Error: no such condition + except("ConditionsManager","+++ update_expired: Cannot update condition %s.%s [%s] to iov:%s.", + condition->detector.path().c_str(), condition->name.c_str(), + condition->iov->str().c_str(), required_validity.str().c_str()); + } + } + updates = upda; +} diff --git a/DDCond/src/ConditionsInterna.cpp b/DDCond/src/ConditionsInterna.cpp index f7c3be8af..140893c53 100644 --- a/DDCond/src/ConditionsInterna.cpp +++ b/DDCond/src/ConditionsInterna.cpp @@ -15,7 +15,6 @@ // Framework include files #include "DD4hep/LCDD.h" #include "DD4hep/Errors.h" -#include "DD4hep/Memory.h" #include "DD4hep/Plugins.h" #include "DD4hep/Printout.h" #include "DD4hep/World.h" @@ -44,26 +43,16 @@ DD4HEP_INSTANTIATE_HANDLE_NAMED(Interna::ConditionsManagerObject); #define NO_AGE 0 -namespace { - int s_debug = INFO; - - int install_cond_mgr (Geometry::LCDD& lcdd, int /* argc */, char** /* argv */) { - typedef Interna::ConditionsManagerObject ConditionsManagerObject; - Handle<ConditionsManagerObject> mgr(lcdd.extension<ConditionsManagerObject>(false)); - if ( !mgr.isValid() ) { - ConditionsManager mgr_handle(lcdd); - lcdd.addExtension<ConditionsManagerObject>(mgr_handle.ptr()); - printout(INFO,"ConditionsManager","+++ Successfully installed conditions manager instance."); - } - return 1; - } -} -DECLARE_APPLY(DD4hepConditionsManagerInstaller,install_cond_mgr) - namespace { + struct Range {}; + struct Discrete {}; + + int s_debug = INFO; + /// Helper: IOV Check function declaration template <typename T> const IOVType* check_iov_type(const ConditionsManagerObject* o, const IOV* iov); + /// Helper: Specialized IOV check template <> const IOVType* check_iov_type<void>(const ConditionsManagerObject* o, const IOV* iov) { if ( iov ) { const IOVType* typ = iov->iovType ? iov->iovType : o->iovType(iov->type); @@ -80,23 +69,24 @@ namespace { return 0; } - struct Range {}; - struct Discrete {}; - + /// Helper: Specialized IOV check for discrete IOV values template <> const IOVType* check_iov_type<Discrete>(const ConditionsManagerObject* o, const IOV* iov) { const IOVType* typ = check_iov_type<void>(o,iov); if ( typ && !iov->has_range() ) return typ; return 0; } + /// Helper: Specialized IOV check for range IOV values template <> const IOVType* check_iov_type<Range>(const ConditionsManagerObject* o, const IOV* iov) { const IOVType* typ = check_iov_type<void>(o,iov); if ( typ && iov->has_range() ) return typ; return 0; } + + /// Helper: Check conditions result for consistency template <typename T> void __check_values__(const ConditionsManagerObject* o, - Geometry::DetElement det, - const std::string& cond, - const IOV* iov) + Geometry::DetElement det, + const std::string& cond, + const IOV* iov) { if ( !iov ) { except("ConditionsManager","+++ Invalid IOV to access condition: %s.%s. [Null-reference]", @@ -115,14 +105,14 @@ namespace { } } - + /// Helper: Check if the conditions range covers the entire IOV span bool is_range_complete(const IOV& iov, const RangeConditions& conditions) { if ( !conditions.empty() ) { // We need to check if the entire range is covered. // For every key.second we must find a key.first, which is at least as big IOV::Key test=iov.keyData; - /// The range may be returned unordered. Hence, - /// we have to try to match at most conditions.size() times until we really know + // The range may be returned unordered. Hence, + // we have to try to match at most conditions.size() times until we really know for(size_t j = 0; j < conditions.size(); ++j ) { for(RangeConditions::const_iterator i=conditions.begin(); i!=conditions.end(); ++i) { const IOV::Key& k = (*i)->iov->key(); @@ -144,6 +134,7 @@ namespace { c->iov->str().c_str(), c->value.c_str()); } } + /// Helper class to be injected into the world object to allow loading from DetElements directly..... struct lcdd_cond_loader : public ConditionsLoader { ConditionsManager m_manager; @@ -153,95 +144,21 @@ namespace { virtual Condition get(Geometry::DetElement element, const std::string& key, const IOV& iov) { return m_manager->get(element, key, iov); } - }; - - -} - -/// Default constructor -IOVPool::IOVPool() { -} - -/// Default destructor -IOVPool::~IOVPool() { -} - -static inline bool key_contains_range(const IOV::Key& key, const IOV::Key& test) { - return key.first <= test.first && key.second >= test.second; -} - -void IOVPool::__find(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& result) -{ - for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { - if ( key_contains_range((*i).first, req_validity.key()) ) { - (*i).second->select(detector, condition_name, result); - } - } -} - -void IOVPool::__find_range(DetElement detector, - const std::string& condition_name, - const IOV& req_validity, - RangeConditions& result) -{ - const IOV::Key& range = req_validity.key(); - for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { - const IOV::Key& key = (*i).first; - if ( IOV::key_is_contained(key,range) ) - // IOV test contained in key. Take it! - (*i).second->select(detector, condition_name, result); - else if ( IOV::key_overlaps_lower_end(key,range) ) - // IOV overlap on test on the lower end of key - (*i).second->select(detector, condition_name, result); - else if ( IOV::key_overlaps_higher_end(key,range) ) - // IOV overlap of test on the higher end of key - (*i).second->select(detector, condition_name, result); - } -} + }; -/// Select all ACTIVE conditions, which do no longer match the IOV requirement -void IOVPool::__select_expired(const IOV& required_validity, RangeConditions& result) { - for(Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { - ConditionsPool* pool = (*i).second; - if ( !key_contains_range((*i).first, required_validity.key()) ) { - if ( pool->age_value == ConditionsPool::AGE_NONE ) { - // Now check the content: - pool->select_used(result); - } - ++pool->age_value; - continue; + int install_cond_mgr (Geometry::LCDD& lcdd, int /* argc */, char** /* argv */) { + typedef Interna::ConditionsManagerObject ConditionsManagerObject; + Handle<ConditionsManagerObject> mgr(lcdd.extension<ConditionsManagerObject>(false)); + if ( !mgr.isValid() ) { + ConditionsManager mgr_handle(lcdd); + lcdd.addExtension<ConditionsManagerObject>(mgr_handle.ptr()); + printout(INFO,"ConditionsManager","+++ Successfully installed conditions manager instance."); } - pool->age_value = 0; + return 1; } } -/// Select all ACTIVE conditions, which do no longer match the IOV requirement -void IOVPool::__update_expired(Interna::ConditionsManagerObject* caller, - ConditionsPool* new_pool, - RangeConditions& updates, - const IOV& required_validity) { - RangeConditions upda; - for(RangeConditions::const_iterator i=updates.begin(); i!=updates.end(); ++i) { - Condition::Object* condition = (*i).ptr(); - - Condition c = new_pool->exists(condition); - if ( c.isValid() ) { - upda.push_back(c); - continue; - } - size_t items = caller->m_loader->load(condition->detector,condition->name,required_validity,upda); - if ( items < 1 ) { - // Error: no such condition - except("ConditionsManager","+++ update_expired: Cannot update condition %s.%s [%s] to iov:%s.", - condition->detector.path().c_str(), condition->name.c_str(), - condition->iov->str().c_str(), required_validity.str().c_str()); - } - } - updates = upda; -} +DECLARE_APPLY(DD4hepConditionsManagerInstaller,install_cond_mgr) /// Standard constructor ConditionsManagerObject::ConditionsManagerObject(LCDD& lcdd) @@ -262,7 +179,7 @@ ConditionsManagerObject::ConditionsManagerObject(LCDD& lcdd) /// Default destructor ConditionsManagerObject::~ConditionsManagerObject() { - for_each(m_pool.begin(), m_pool.end(), DestroyObject<IOVPool*>()); + for_each(m_pool.begin(), m_pool.end(), DestroyObject<ConditionsIOVPool*>()); InstanceCount::decrement(this); } @@ -300,7 +217,7 @@ pair<bool, const IOVType*> ConditionsManagerObject::registerIOVType(size_t iov_t } t.name = iov_name; t.type = iov_type; - m_pool[t.type] = new IOVPool(); + m_pool[t.type] = new ConditionsIOVPool(); return make_pair(true,&t); } except("ConditionsManager","Cannot register IOV section %d of type %d. Value out of bounds: [%d,%d]", @@ -363,12 +280,12 @@ ConditionsPool* ConditionsManagerObject::registerIOV(const string& data) { ConditionsPool* ConditionsManagerObject::registerIOV(const IOVType& typ, IOV::Key key) { // IOV read and checked. Now register it, but always locked! - IOVPool* pool = m_pool[typ.type]; + ConditionsIOVPool* pool = m_pool[typ.type]; dd4hep_lock_t lock(m_poolLock); if ( !pool ) { - m_pool[typ.type] = pool = new IOVPool(); + m_pool[typ.type] = pool = new ConditionsIOVPool(); } - IOVPool::Entries::const_iterator i = pool->entries.find(key); + ConditionsIOVPool::Entries::const_iterator i = pool->entries.find(key); if ( i != pool->entries.end() ) { return (*i).second; } @@ -386,7 +303,7 @@ ConditionsPool* ConditionsManagerObject::registerIOV(const IOVType& typ, IOV::Ke Condition ConditionsManagerObject::__queue_update(Entry* e) { if ( e ) { ConditionsPool* p = registerIOV(e->validity); - Condition c = m_updatePool->insert(p, e); + Condition c = m_updatePool->insertEntry(p, e); if ( s_debug > INFO ) { printout(INFO,"Conditions","+++ Loaded condition: %s.%s to %s [%s] V: %s", c.detector().path().c_str(), c.name().c_str(), c->value.c_str(), @@ -440,7 +357,7 @@ void ConditionsManagerObject::prepare(const IOV& required_validity) { const IOVType* typ = check_iov_type<Discrete>(this, &required_validity); if ( typ ) { ConditionsPool* cp = 0; - IOVPool* pool = m_pool[typ->type]; + ConditionsIOVPool* pool = m_pool[typ->type]; if ( pool ) {{ dd4hep_lock_t lock(m_poolLock); cp = registerIOV(*typ, required_validity.key()); @@ -451,7 +368,7 @@ void ConditionsManagerObject::prepare(const IOV& required_validity) { pushUpdates(); RangeConditions updates; pool->__select_expired(required_validity, updates); - pool->__update_expired(this, cp, updates, required_validity); + pool->__update_expired(*m_loader, *cp, updates, required_validity); cp->updates->insert(updates); } return; @@ -463,13 +380,13 @@ void ConditionsManagerObject::prepare(const IOV& required_validity) { /// Enable all updates to the clients with the defined IOV void ConditionsManagerObject::enable(const IOV& required_validity) { if ( !locked ) { - IOVPool* pool = m_pool[required_validity.type]; + ConditionsIOVPool* pool = m_pool[required_validity.type]; if ( pool ) { ReplacementPool* rep_pool = 0; pushUpdates(); { dd4hep_lock_t lock(m_poolLock); - IOVPool::Entries::iterator i = pool->entries.find(required_validity.key()); + ConditionsIOVPool::Entries::iterator i = pool->entries.find(required_validity.key()); if ( i == pool->entries.end() ) { except("ConditionsManager","+++ Unknown IOV [%s] requested to enable conditions. [%s]", required_validity.str().c_str(), Errors::invalidArg().c_str()); @@ -500,10 +417,10 @@ void ConditionsManagerObject::registerCondition(Condition c) { // Check arguments. This also checks the existence of the proper pool __check_values__<Discrete>(this,det,c.name(),iov); - IOVPool* pool = m_pool[iov->type]; + ConditionsIOVPool* pool = m_pool[iov->type]; { // We are now modifying the pool: need to lock any access dd4hep_lock_t lock(m_poolLock); - IOVPool::Entries::iterator it = pool->entries.find(iov->keyData); + ConditionsIOVPool::Entries::iterator it = pool->entries.find(iov->keyData); if ( it != pool->entries.end() ) { (*it).second->insert(c); return; @@ -522,10 +439,10 @@ bool ConditionsManagerObject::__find(DetElement det, const std::string& cond, const IOV& req_validity, RangeConditions& conditions) { - IOVPool* p = 0; + ConditionsIOVPool* p = 0; { dd4hep_lock_t locked_action(m_poolLock); - p = m_pool[req_validity.type]; // Already checked by upper level! + p = m_pool[req_validity.type]; // Existence already checked by caller! p->__find(det, cond, req_validity, conditions); } { @@ -541,10 +458,10 @@ bool ConditionsManagerObject::__find_range(DetElement det, const IOV& req_validity, RangeConditions& conditions) { - IOVPool* p = 0; + ConditionsIOVPool* p = 0; { dd4hep_lock_t locked_action(m_poolLock); - p = m_pool[req_validity.type]; // Existence alread checked! + p = m_pool[req_validity.type]; // Existence alread checked by caller! p->__find_range(det, cond, req_validity, conditions); } { diff --git a/DDCond/src/ConditionsLinearPool.cpp b/DDCond/src/ConditionsLinearPool.cpp index 54fc79604..f3650360c 100644 --- a/DDCond/src/ConditionsLinearPool.cpp +++ b/DDCond/src/ConditionsLinearPool.cpp @@ -59,7 +59,7 @@ namespace DD4hep { } /// Register a new condition to this pool - virtual Condition insert(ConditionsPool* pool, Entry* cond) { + virtual Condition insertEntry(ConditionsPool* pool, Entry* cond) { MAPPING& m = this->ConditionsLinearPool<MAPPING,BASE>::m_conditions; Condition c = this->create(pool, cond); m.insert(m.end(),c.ptr()); diff --git a/DDCond/src/ConditionsPool.cpp b/DDCond/src/ConditionsPool.cpp index df9aadebf..ebed15f67 100644 --- a/DDCond/src/ConditionsPool.cpp +++ b/DDCond/src/ConditionsPool.cpp @@ -55,9 +55,6 @@ Condition ConditionsPool::create(ConditionsPool* pool, const Entry* entry) { return c; } -/// Insert a set of conditions -RangeConditions& conditions(); - /// Default constructor UpdatePool::UpdatePool() : ConditionsPool() { diff --git a/DDCond/src/ConditionsTest.cpp b/DDCond/src/ConditionsTest.cpp index 2011ebfee..30044ca63 100644 --- a/DDCond/src/ConditionsTest.cpp +++ b/DDCond/src/ConditionsTest.cpp @@ -15,7 +15,13 @@ // Framework include files #include "DD4hep/DetectorTools.h" #include "ConditionsTest.h" + +// C/C++ include files #include <vector> +#include <list> +#include <set> +#include <map> +#include <deque> using namespace std; using namespace DD4hep::Conditions; @@ -29,73 +35,73 @@ namespace DD4hep { /// Namespace for test environments in DDCond namespace Test { + template <typename T> void print_bound_condition(Condition c, const char* norm) {} + - template<typename T> void __print_bound_val(Condition c, const char* norm, const char* fmt) { + template<typename T> void __print_bound_val(Condition c, const char* norm) { const char* test = c.detector().name(); char text_format[1024]; - c.bind<T>(); - T value = c.get<T>(); + const T& value = access_val<T>(c); if ( norm ) { T val = _multiply(c.get<T>(),norm); - ::snprintf(text_format,sizeof(text_format)," Bound value %%s : value:%s [%s] Type: %%s",fmt,fmt); + ::snprintf(text_format,sizeof(text_format)," Bound value %%s : value:%s [%s] Type: %%s", + Primitive<T>::default_format(),Primitive<T>::default_format()); printout(INFO,test,text_format, c.name().c_str(), value, val, typeName(c.typeInfo()).c_str()); return; } - ::snprintf(text_format,sizeof(text_format)," Bound value %%s : value:%s Type: %%s",fmt); + ::snprintf(text_format,sizeof(text_format)," Bound value %%s : value:%s Type: %%s", + Primitive<T>::default_format()); printout(INFO,test,text_format, c.name().c_str(), value, typeName(c.typeInfo()).c_str()); } - - template void __print_bound_val<short>(Condition c, const char* norm, const char* fmt); - template void __print_bound_val<int>(Condition c, const char* norm, const char* fmt); - template void __print_bound_val<long>(Condition c, const char* norm, const char* fmt); - template void __print_bound_val<unsigned short>(Condition c, const char* norm, const char* fmt); - template void __print_bound_val<unsigned int>(Condition c, const char* norm, const char* fmt); - template void __print_bound_val<unsigned long>(Condition c, const char* norm, const char* fmt); - template void __print_bound_val<float>(Condition c, const char* norm, const char* fmt); - template void __print_bound_val<double>(Condition c, const char* norm, const char* fmt); - - template <> void print_bound_value<string>(Condition c, const char*) { + template <> void __print_bound_val<string>(Condition c, const char*) { const char* test = c.detector().name(); - c.bind<string>(); - printout(INFO,test," Bound value %s : string value:%s Type: %s", - c.name().c_str(), c.get<string>().c_str(),typeName(c.typeInfo()).c_str()); + const string& v = access_val<string>(c); + printout(INFO,test," Bound value %s : string value:%s Type: %s Ptr:%016X", + c.name().c_str(), c.get<string>().c_str(),typeName(c.typeInfo()).c_str(), + (void*)&v); } - - template <> void print_bound_value<short>(Condition c, const char* norm) - { __print_bound_val<short>(c, norm, "%d"); } - - template <> void print_bound_value<int>(Condition c, const char* norm) - { __print_bound_val<int>(c, norm, "%d"); } - - template <> void print_bound_value<long>(Condition c, const char* norm) - { __print_bound_val<long>(c, norm, "%d"); } - - template <> void print_bound_value<unsigned short>(Condition c, const char* norm) - { __print_bound_val<unsigned short>(c, norm, "%d"); } - - template <> void print_bound_value<unsigned int>(Condition c, const char* norm) - { __print_bound_val<unsigned int>(c, norm, "%d"); } - - template <> void print_bound_value<unsigned long>(Condition c, const char* norm) - { __print_bound_val<unsigned long>(c, norm, "%d"); } - - template <> void print_bound_value<float>(Condition c, const char* norm) - { __print_bound_val<float>(c, norm, "%g"); } - - template <> void print_bound_value<double>(Condition c, const char* norm) - { __print_bound_val<double>(c, norm, "%g"); } - - - template <> void print_bound_value<vector<double> >(Condition c, const char*) { + template <typename T> void __print_bound_container(Condition c, const char*) { const char* test = c.detector().name(); - c.bind<vector<double> >(); - const vector<double>& v = c.get<vector<double> >(); - printout(INFO,test," Bound value %s : size:%d = %s Type: %s", + const T& v = access_val<T>(c); + printout(INFO,test," Bound value %s : size:%d = %s Type: %s Ptr:%016X", c.name().c_str(), int(v.size()), c.block().str().c_str(), - typeName(c.typeInfo()).c_str()); + typeName(c.typeInfo()).c_str(), (void*)&v); } + +#define TEMPLATE_SIMPLE_TYPE(x) \ + template <> void print_bound_value<x>(Condition c, const char* norm) \ + { __print_bound_val<x>(c, norm); } + +#define TEMPLATE_CONTAINER_TYPE(container,x) \ + template void __print_bound_container<container >(Condition c, const char* norm); \ + template <> void print_bound_value<container >(Condition c, const char* norm) \ + { __print_bound_container<container >(c, norm); } + +#define TEMPLATE_TYPE(x,f) \ + TEMPLATE_SIMPLE_TYPE(x) \ + TEMPLATE_CONTAINER_TYPE(vector<x>,x) \ + TEMPLATE_CONTAINER_TYPE(list<x>,x) \ + TEMPLATE_CONTAINER_TYPE(set<x>,x) \ + TEMPLATE_CONTAINER_TYPE(deque<x>,x) \ + TEMPLATE_CONTAINER_TYPE(Primitive<x>::int_map_t,x) \ + TEMPLATE_CONTAINER_TYPE(Primitive<x>::size_map_t,x) \ + TEMPLATE_CONTAINER_TYPE(Primitive<x>::string_map_t,x) + + + TEMPLATE_TYPE(char,"%c") + TEMPLATE_TYPE(unsigned char,"%02X") + TEMPLATE_TYPE(short,"%d") + TEMPLATE_TYPE(unsigned short,"%04X") + TEMPLATE_TYPE(int,"%d") + TEMPLATE_TYPE(unsigned int,"%08X") + TEMPLATE_TYPE(long,"%ld") + TEMPLATE_TYPE(unsigned long,"%016X") + TEMPLATE_TYPE(float,"%f") + TEMPLATE_TYPE(double,"%g") + TEMPLATE_TYPE(std::string,"%c") + template <> void print_condition<void>(Condition c) { const char* test = c.detector().name(); string type = c.type(); @@ -122,8 +128,8 @@ namespace DD4hep { print_bound_value<unsigned int>(c); else if ( type == "unsigned long" ) print_bound_value<unsigned long>(c); - else if ( type == "double" ) - print_bound_value<double>(c); + else if ( type == "float" ) + print_bound_value<float>(c); else if ( type == "double" ) print_bound_value<double>(c); else if ( type == "vector<double>" ) @@ -192,16 +198,16 @@ void Test::TestEnv::add_xml_data_source(const string& file) { void Test::TestEnv::dump_conditions_pools() { typedef RangeConditions _R; - typedef IOVPool::Entries _E; + typedef ConditionsIOVPool::Entries _E; typedef Interna::ConditionsManagerObject::TypedConditionPool _P; int cnt = 0; _P& p = this->manager->m_pool; for(_P::const_iterator i=p.begin(); i != p.end(); ++i, ++cnt) { - IOVPool* pool = (*i); + ConditionsIOVPool* pool = (*i); if ( pool ) { const _E& e = pool->entries; const IOVType* typ = this->manager->iovType(cnt); - printout(INFO,"Example","+++ IOVPool for type %s", typ->str().c_str()); + printout(INFO,"Example","+++ ConditionsIOVPool for type %s", typ->str().c_str()); for (_E::const_iterator j=e.begin(); j != e.end(); ++j) { _R rc; ConditionsPool* cp = (*j).second; diff --git a/DDCond/src/ConditionsTest.h b/DDCond/src/ConditionsTest.h index 6ee5128d8..4f48943d5 100644 --- a/DDCond/src/ConditionsTest.h +++ b/DDCond/src/ConditionsTest.h @@ -21,6 +21,7 @@ #include "DD4hep/DetFactoryHelper.h" #include "DDCond/ConditionsManager.h" +#include "DDCond/ConditionsIOVPool.h" #include "DDCond/ConditionsInterna.h" /// Namespace for the AIDA detector description toolkit @@ -52,13 +53,19 @@ namespace DD4hep { void dump_conditions_pools(); static void dump_detector_element(DetElement elt); static void dump_conditions_tree(DetElement elt); - }; template <typename T> void print_condition(Condition condition); template <typename T> void print_bound_value(Condition condition, const char* norm=0); template <typename T> void print_conditions(const RangeConditions& rc); void check_discrete_condition(Condition c, const IOV& iov); + + template<typename T> const T& access_val(Condition c) { + if ( !c->is_bound() ) { + c.bind<T>(); + } + return c.get<T>(); + } } } } diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h index 94a2f47d9..8af4b3f06 100644 --- a/DDCore/include/DD4hep/Conditions.h +++ b/DDCore/include/DD4hep/Conditions.h @@ -96,28 +96,34 @@ namespace DD4hep { /// Create string representation of the IOV std::string str() const; /// Check if the IOV corresponds to a range - bool has_range() const { return keyData.first != keyData.second; } + bool has_range() const { return keyData.first != keyData.second; } /// Check if the IOV corresponds to a range - bool is_discrete() const { return keyData.first == keyData.second; } + bool is_discrete() const { return keyData.first == keyData.second; } /// Get the local key of the IOV - Key key() const { return keyData; } + Key key() const { return keyData; } /// Check for validity containment /** Check if the caller 'iov' is of the same type and the range * is fully conained by the caller. */ bool contains(const IOV& iov) const; - static bool same_type(const IOV& iov, const IOV& test) { + /// Check if 2 IOV objects are of the same type + static bool same_type(const IOV& iov, const IOV& test) { unsigned int typ1 = iov.iovType ? iov.iovType->type : iov.type; unsigned int typ2 = test.iovType ? test.iovType->type : test.type; return typ1 == typ2; } - static bool key_is_contained(const IOV::Key& key, const IOV::Key& test) + /// Check if IOV 'test' is fully contained in IOV 'key' + static bool key_is_contained(const Key& key, const Key& test) { return key.first >= test.first && key.second <= test.second; } - static bool key_overlaps_lower_end(const IOV::Key& key, const IOV::Key& test) + /// Same as above, but reverse logic. Gives sometimes more understandable logic. + static bool key_contains_range(const Key& key, const Key& test) + { return key.first <= test.first && key.second >= test.second; } + /// Check if IOV 'test' has an overlap on the lower interval edge with IOV 'key' + static bool key_overlaps_lower_end(const Key& key, const Key& test) { return key.first <= test.second && key.first >= test.first; } - static bool key_overlaps_higher_end(const IOV::Key& key, const IOV::Key& test) + /// Check if IOV 'test' has an overlap on the upper interval edge with IOV 'key' + static bool key_overlaps_higher_end(const Key& key, const Key& test) { return key.second >= test.first && key.second <= test.second; } - }; @@ -152,6 +158,8 @@ namespace DD4hep { void fromString(const std::string& rep); /// Create string representation of the data block std::string str(); + /// Check if object is already bound.... + bool is_bound() const { return 0 != pointer; } /// Generic getter. Specify the exact type, not a polymorph type template <typename T> inline T& get(); /// Generic getter (const version). Specify the exact type, not a polymorph type diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h index 551c4d955..ef0e4583c 100644 --- a/DDCore/include/DD4hep/Handle.h +++ b/DDCore/include/DD4hep/Handle.h @@ -176,15 +176,15 @@ namespace DD4hep { return *(Q*) m_element; } /// Checked object access. Throws invalid handle runtime exception - T* access() const; + T* access() const throw(std::exception); /// Verify the object type after a (re-)assignment - void verifyObject() const; + void verifyObject() const throw(std::exception); /// Access the object name (or "" if not supported by the object) const char* name() const; - /// Helper routine called when unrelated types are assigned. - static void bad_assignment(const std::type_info& from, const std::type_info& to); /// Assign a new named object. Note: object references must be managed by the user void assign(Implementation* n, const std::string& nam, const std::string& title); + /// Helper routine called when unrelated types are assigned. + static void bad_assignment(const std::type_info& from, const std::type_info& to) throw(std::exception); }; /// Default Ref_t definition describing named objects \ingroup DD4HEP_GEOMETRY typedef Handle<NamedObject> Ref_t; diff --git a/DDCore/include/DD4hep/Handle.inl b/DDCore/include/DD4hep/Handle.inl index e6bdeb0c6..de5189870 100644 --- a/DDCore/include/DD4hep/Handle.inl +++ b/DDCore/include/DD4hep/Handle.inl @@ -19,7 +19,9 @@ namespace DD4hep { /// Helper routine called when unrelated types are assigned. - template <typename T> void Handle<T>::bad_assignment(const std::type_info& from, const std::type_info& to) { + template <typename T> void Handle<T>::bad_assignment(const std::type_info& from, const std::type_info& to) + throw(std::exception) + { invalidHandleAssignmentError(from,to); } @@ -38,7 +40,7 @@ namespace DD4hep { } /// Checked object access. Throws invalid handle runtime exception - template <typename T> T* Handle<T>::access() const { + template <typename T> T* Handle<T>::access() const throw(std::exception) { if ( this->m_element ) return this->m_element; invalidHandleError(typeid(T)); return 0; // We have thrown an exception before - does not harm! @@ -48,7 +50,9 @@ namespace DD4hep { #define DD4HEP_INSTANTIATE_HANDLE(X) \ namespace DD4hep { \ - template <> void Handle<X>::verifyObject() const { \ + template <> void Handle<X>::verifyObject() const \ + throw(std::exception) \ + { \ increment_object_validations(); \ if (m_element && dynamic_cast<X*>((TObject*)m_element) == 0) { \ bad_assignment(typeid(*m_element), typeid(X)); \ @@ -66,7 +70,9 @@ namespace DD4hep { p->name = n; \ p->type = t; \ } \ - template <> void Handle<X>::verifyObject() const { \ + template <> void Handle<X>::verifyObject() const \ + throw(std::exception) \ + { \ increment_object_validations(); \ if (m_element && dynamic_cast<X*>((NamedObject*)m_element) == 0) {\ bad_assignment(typeid(*m_element), typeid(X)); \ diff --git a/DDCore/include/DD4hep/Parsers.h b/DDCore/include/DD4hep/Parsers.h index 3aa506987..fb2652384 100644 --- a/DDCore/include/DD4hep/Parsers.h +++ b/DDCore/include/DD4hep/Parsers.h @@ -23,6 +23,7 @@ #include <list> #include <set> #include <map> +#include <deque> #include "Math/Point3D.h" #include "Math/Vector3D.h" #include "Math/Vector4D.h" @@ -34,10 +35,18 @@ #define PARSERS_DECL_FOR_PAIR(FirstType, SecondType) \ int parse(std::pair<FirstType, SecondType >& result,const std::string& input); -#define PARSERS_DECL_FOR_LIST(InnerType) \ - int parse(std::vector<InnerType>& result,const std::string& input); \ - int parse(std::list<InnerType>& result,const std::string& input); \ - int parse(std::set<InnerType>& result,const std::string& input); +#define PARSERS_DECL_FOR_LIST(InnerType) \ + int parse(std::vector<InnerType >& result,const std::string& input); \ + int parse(std::list<InnerType >& result,const std::string& input); \ + int parse(std::set<InnerType >& result,const std::string& input); \ + int parse(std::deque<InnerType >& result,const std::string& input); \ + int parse(std::map<std::string,InnerType >& result,const std::string& input); \ + int parse(std::map<int,InnerType >& result,const std::string& input); \ + int parse(std::map<unsigned long,InnerType >& result,const std::string& input); \ + int parse(std::pair<std::string,InnerType >& result,const std::string& input); \ + int parse(std::pair<int,InnerType >& result,const std::string& input); \ + int parse(std::pair<unsigned long,InnerType >& result,const std::string& input); + // ============================================================================ /** @file * The declaration of major parsing functions used e.g @@ -670,6 +679,7 @@ namespace DD4hep { * @date 2009-09-05 */ int parse(ROOT::Math::PxPyPzEVector& result, const std::string& input); + // ======================================================================== /// parse the vector of points /** @param result (OUTPUT) the parser vector @@ -677,9 +687,8 @@ namespace DD4hep { * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl * @date 2009-09-05 */ - int parse( std::vector<ROOT::Math::XYZPoint>& result, const std::string& input); - int parse( std::list<ROOT::Math::XYZPoint>& result, const std::string& input); - int parse( std::set<ROOT::Math::XYZPoint>& result, const std::string& input); + PARSERS_DECL_FOR_LIST(ROOT::Math::XYZPoint) + // ======================================================================== /// parse the vector of vectors /** @param result (OUTPUT) the parser vector @@ -687,9 +696,8 @@ namespace DD4hep { * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl * @date 2009-09-05 */ - int parse( std::vector<ROOT::Math::XYZVector>& result, const std::string& input); - int parse( std::list<ROOT::Math::XYZVector>& result, const std::string& input); - int parse( std::set<ROOT::Math::XYZVector>& result, const std::string& input); + PARSERS_DECL_FOR_LIST(ROOT::Math::XYZVector) + // ======================================================================== /// parse the vector of vectors /** @param result (OUTPUT) the parser vector @@ -697,9 +705,7 @@ namespace DD4hep { * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl * @date 2009-09-05 */ - int parse(std::vector<ROOT::Math::PxPyPzEVector>& result, const std::string& input); - int parse(std::list<ROOT::Math::PxPyPzEVector>& result, const std::string& input); - int parse(std::set<ROOT::Math::PxPyPzEVector>& result, const std::string& input); + PARSERS_DECL_FOR_LIST(ROOT::Math::PxPyPzEVector) // ======================================================================== }// end of namespace Parsers diff --git a/DDCore/include/DD4hep/Primitives.h b/DDCore/include/DD4hep/Primitives.h index b62e2f45a..2d3213b81 100644 --- a/DDCore/include/DD4hep/Primitives.h +++ b/DDCore/include/DD4hep/Primitives.h @@ -18,6 +18,7 @@ #include "DDSegmentation/Segmentation.h" // C/C++ include files +#include <limits> #include <algorithm> /// Namespace for the AIDA detector description toolkit @@ -45,6 +46,20 @@ namespace DD4hep { inline unsigned int hash32(const std::string& key) { return hash32(key.c_str()); } + + /// Specialized exception to be thrown if invalid handles are accessed + class invalid_handle_exception : public std::runtime_error { + public: + /// Initializing constructor + invalid_handle_exception(const char* msg) : std::runtime_error(msg) {} + /// Initializing constructor + invalid_handle_exception(const std::string& msg) : std::runtime_error(msg) {} + /// Generic copy constructor + invalid_handle_exception(const std::exception& e) : std::runtime_error(e.what()) {} + /// Default destructor of specialized exception + virtual ~invalid_handle_exception(); + }; + /// ABI information about type names std::string typeName(const std::type_info& type); void typeinfoCheck(const std::type_info& typ1, const std::type_info& typ2, const std::string& text = "") throw(std::exception); @@ -61,6 +76,70 @@ namespace DD4hep { /// Throw exception when handles are check for validity void notImplemented(const std::string& msg) throw(std::exception); + + /// A bit of support for printing primitives + /** + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP + */ + template<typename T> struct Primitive { + public: + /// Type decribed by th class + typedef T value_t; + /// Definition of the vector type + typedef std::vector<value_t> vector_t; + + /// Definition of the short integer mapped type + typedef std::pair<short,value_t> short_pair_t; + /// Definition of the unsigned short integer mapped type + typedef std::pair<unsigned short,value_t> ushort_pair_t; + /// Definition of the integer mapped type + typedef std::pair<int,value_t> int_pair_t; + /// Definition of the unsigned integer mapped type + typedef std::pair<unsigned int,value_t> uint_pair_t; + /// Definition of the long integer mapped type + typedef std::pair<long,value_t> long_pair_t; + /// Definition of the unsigned long integer mapped type + typedef std::pair<unsigned long,value_t> ulong_pair_t; + /// Definition of the size_t mapped type + typedef std::pair<size_t,value_t> size_pair_t; + /// Definition of the string mapped type + typedef std::pair<std::string,value_t> string_pair_t; + + /// Definition of the short integer mapped type + typedef std::map<short,value_t> short_map_t; + /// Definition of the unsigned short integer mapped type + typedef std::map<unsigned short,value_t> ushort_map_t; + /// Definition of the integer mapped type + typedef std::map<int,value_t> int_map_t; + /// Definition of the unsigned integer mapped type + typedef std::map<unsigned int,value_t> uint_map_t; + /// Definition of the long integer mapped type + typedef std::map<long,value_t> long_map_t; + /// Definition of the unsigned long integer mapped type + typedef std::map<unsigned long,value_t> ulong_map_t; + /// Definition of the size_t mapped type + typedef std::map<size_t,value_t> size_map_t; + /// Definition of the string mapped type + typedef std::map<std::string,value_t> string_map_t; + /// Definition of the limits + typedef std::numeric_limits<value_t> limits; + + /// Access to default printf format + static const char* default_format(); + /// Access to the specific printf format. May be overloaded by users + static const char* format() { return default_format(); } + /// Access to the RTTI data type + static const std::type_info& type() { return typeid(value_t); } + /// Access to the RTTI data type + static std::string type_name() { return typeName(type()); } + /// Auto conversion to string using the default format + static std::string toString(T value); + }; + + /// Class to perform dynamic casts using unknown pointers. /** @class ComponentCast Primitives.h DD4hep/Primitives.h * diff --git a/DDCore/include/DD4hep/ToStream.h b/DDCore/include/DD4hep/ToStream.h index 34d087e19..ba7ece784 100644 --- a/DDCore/include/DD4hep/ToStream.h +++ b/DDCore/include/DD4hep/ToStream.h @@ -24,6 +24,7 @@ #include <map> #include <set> #include <list> +#include <deque> #include <string> #include <sstream> #include "Math/Point3D.h" @@ -160,6 +161,17 @@ namespace DD4hep { return toStream(obj.begin(), obj.end(), s, "[ ", " ]", " , "); } // ======================================================================== + /** the partial template specialization of <c>std::deque<TYPE,ALLOCATOR></c> + * printout. The vector is printed a'la Python list: "[ a, b, c ]" + * @author Alexander MAZUROV Alexander.Mazurov@gmail.com + * @author Vanya BELYAEV ibelyaev@physics.syr.edu + * @date 2006-05-12 + */ + template <class TYPE, class ALLOCATOR> + inline std::ostream& toStream(const std::deque<TYPE, ALLOCATOR>& obj, std::ostream& s) { + return toStream(obj.begin(), obj.end(), s, "[ ", " ]", " , "); + } + // ======================================================================== /** the partial template specialization of <c>std::set<TYPE,CMP,ALLOCATOR></c> * printout. The vector is printed a'la Python list: "[ a, b, c ]" * @author Alexander MAZUROV Alexander.Mazurov@gmail.com diff --git a/DDCore/include/DD4hep/objects/BasicGrammar_inl.h b/DDCore/include/DD4hep/objects/BasicGrammar_inl.h index 50f7ff56a..5a2d03f4f 100644 --- a/DDCore/include/DD4hep/objects/BasicGrammar_inl.h +++ b/DDCore/include/DD4hep/objects/BasicGrammar_inl.h @@ -11,11 +11,11 @@ // Author : M.Frank // //========================================================================== - #ifndef DD4HEP_DDG4_GRAMMAR_INL_H #define DD4HEP_DDG4_GRAMMAR_INL_H // Framework include files +#include "DD4hep/Primitives.h" #include "DD4hep/BasicGrammar.h" #ifdef DD4HEP_USE_BOOST @@ -33,6 +33,7 @@ #include <list> #include <set> #include <map> +#include <deque> namespace DD4hep { XmlTools::Evaluator& g4Evaluator(); } namespace { static XmlTools::Evaluator& s__eval(DD4hep::g4Evaluator()); } @@ -193,6 +194,30 @@ namespace DD4hep { return 1; } + /// Insertion function for std sets + template <typename TYPE> static int fill_data(std::deque<TYPE>* p,const std::vector<std::string>& temp) { + const BasicGrammar& g = BasicGrammar::instance<TYPE>(); + TYPE val; + for(std::vector<std::string>::const_iterator i=temp.begin(); i != temp.end(); ++i) { + if ( !g.fromString(&val,*i) ) + return 0; + p->push_back(val); + } + return 1; + } + + /// Insertion function for std sets + template <typename KEY, typename TYPE> static int fill_data(std::map<KEY,TYPE>* p,const std::vector<std::string>& temp) { + const BasicGrammar& g = BasicGrammar::instance<std::pair<KEY,TYPE> >(); + std::pair<KEY,TYPE> val; + for(std::vector<std::string>::const_iterator i=temp.begin(); i != temp.end(); ++i) { + if ( !g.fromString(&val,*i) ) + return 0; + p->insert(val); + } + return 1; + } + /// Container evaluator template <typename TYPE> static int eval_container(TYPE* p, const std::string& str) { #ifdef DD4HEP_USE_BOOST @@ -222,7 +247,7 @@ namespace DD4hep { } /// Item evaluator - template <typename T> static int eval_item(T* p, std::string s) { + template <typename T> inline int eval_item(T* p, std::string s) { size_t idx = s.find("(int)"); if (idx != std::string::npos) s.erase(idx, 5); @@ -235,9 +260,22 @@ namespace DD4hep { *p = (T)result; return 1; } - + + /// String evaluator + template <> inline int eval_item<std::string>(std::string* p, std::string s) { + *p = s; + return 1; + } + + /// Item evaluator + template <typename T,typename Q> inline int eval_pair(std::pair<T,Q>* p, std::string s) { + const BasicGrammar& g = BasicGrammar::instance<std::pair<T,Q> >(); + if ( !g.fromString(p,s) ) return 0; + return 1; + } + /// Object evaluator - template<typename T> static int eval_obj(T* p, const std::string& str) { + template<typename T> inline int eval_obj(T* p, const std::string& str) { return BasicGrammar::instance<T>().fromString(p,pre_parse_obj(str)); } @@ -245,29 +283,39 @@ namespace DD4hep { } // End namespace DD4hep -#define DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x) namespace DD4hep { \ - template<> const BasicGrammar& BasicGrammar::instance<x>() { static Grammar<x> s; return s;}} +#define DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x) \ +namespace DD4hep { \ + template<> const BasicGrammar& BasicGrammar::instance<x>() { static Grammar<x> s; return s;}} -#define DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func) namespace DD4hep { \ - template<> int Grammar<x >::evaluate(void* p, const std::string& v) const { return func ((x*)p,v); }} +#define DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func) \ + namespace DD4hep { \ + template<> int Grammar<x >::evaluate(void* p, const std::string& v) const { return func ((x*)p,v); }} #define DD4HEP_DEFINE_PARSER_GRAMMAR(x,func) \ DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x) \ DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func) -#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>,eval_container) +#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(std::deque<x>, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_map_t, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::ulong_map_t, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_map_t, eval_container) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::int_pair_t, eval_pair) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::ulong_pair_t, eval_pair) \ + DD4HEP_DEFINE_PARSER_GRAMMAR(DD4hep::Primitive<x>::string_pair_t, eval_pair) #define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func) \ DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func) \ DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \ - DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container) + DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container) -#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x) \ - DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item) \ +#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x) \ + DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item) \ DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(unsigned x,eval_item) + #endif /* DD4HEP_DDG4_GRAMMAR_INL_H */ diff --git a/DDCore/include/DD4hep/objects/ConditionsInterna.h b/DDCore/include/DD4hep/objects/ConditionsInterna.h index c649b30d4..b0d872cee 100644 --- a/DDCore/include/DD4hep/objects/ConditionsInterna.h +++ b/DDCore/include/DD4hep/objects/ConditionsInterna.h @@ -162,6 +162,8 @@ namespace DD4hep { const IOV* iov_data() const; /// Access safely the IOV-type const IOVType* iov_type() const; + /// Check if object is already bound.... + bool is_bound() const { return data.is_bound(); } }; /// The data class behind a conditions container handle. @@ -258,11 +260,14 @@ namespace DD4hep { DD4HEP_DEFINE_CONDITIONS_TYPE(x) \ DD4HEP_DEFINE_CONDITIONS_TYPE(std::vector<x>) \ DD4HEP_DEFINE_CONDITIONS_TYPE(std::list<x>) \ - DD4HEP_DEFINE_CONDITIONS_TYPE(std::set<x>) + DD4HEP_DEFINE_CONDITIONS_TYPE(std::set<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(std::deque<x>) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::int_map_t) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::ulong_map_t) \ + DD4HEP_DEFINE_CONDITIONS_TYPE(DD4hep::Primitive<x>::string_map_t) #define DD4HEP_DEFINE_CONDITIONS_U_CONT(x) \ DD4HEP_DEFINE_CONDITIONS_CONT(x) \ DD4HEP_DEFINE_CONDITIONS_CONT(unsigned x) - #endif /* DD4HEP_GEOMETRY_CONDITIONINTERNA_H */ diff --git a/DDCore/src/BasicGrammarTypes.cpp b/DDCore/src/BasicGrammarTypes.cpp index ce98b6514..832d80505 100644 --- a/DDCore/src/BasicGrammarTypes.cpp +++ b/DDCore/src/BasicGrammarTypes.cpp @@ -16,19 +16,20 @@ #include "DD4hep/objects/BasicGrammar_inl.h" namespace ROOT { namespace Math { - static bool operator<(const XYZPoint& a, const XYZPoint& b) { + + bool operator<(const XYZPoint& a, const XYZPoint& b) { if ( a.X() < b.X() ) return true; if ( a.Y() < b.Y() ) return true; if ( a.Z() < b.Z() ) return true; return false; } - static bool operator<(const XYZVector& a, const XYZVector& b) { + bool operator<(const XYZVector& a, const XYZVector& b) { if ( a.X() < b.X() ) return true; if ( a.Y() < b.Y() ) return true; if ( a.Z() < b.Z() ) return true; return false; } - static bool operator<(const PxPyPzEVector& a, const PxPyPzEVector& b) { + bool operator<(const PxPyPzEVector& a, const PxPyPzEVector& b) { if ( a.X() < b.X() ) return true; if ( a.Y() < b.Y() ) return true; if ( a.Z() < b.Z() ) return true; @@ -50,19 +51,7 @@ DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(long long) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(bool,eval_item) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(float,eval_item) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(double,eval_item) - -DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(std::string) -DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(std::vector<std::string>) -DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(std::list<std::string>) -DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(std::set<std::string>) - -// ROOT::Math Object instances -typedef std::map<std::string, int> map_string_int; -DD4HEP_DEFINE_PARSER_GRAMMAR(map_string_int,eval_obj) - -// e.g.,, runHeader map -typedef std::map<std::string, std::string> map_string_string; -DD4HEP_DEFINE_PARSER_GRAMMAR(map_string_string,eval_obj) +DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(std::string,eval_item) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(ROOT::Math::XYZPoint,eval_obj) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(ROOT::Math::XYZVector,eval_obj) diff --git a/DDCore/src/Conditions.cpp b/DDCore/src/Conditions.cpp index 0f5da68ca..8356a094f 100644 --- a/DDCore/src/Conditions.cpp +++ b/DDCore/src/Conditions.cpp @@ -107,7 +107,7 @@ Condition::Condition(const string& nam,const string& typ) : Handle<Object>() { /// Assignment operator Condition& Condition::operator=(const Condition& c) { - if ( this != &c ) this->m_element = c.m_element; + if ( this != &c ) this->m_element = c.m_element; return *this; } @@ -186,8 +186,16 @@ const DD4hep::BasicGrammar& Condition::descriptor() const { /// Re-evaluate the conditions data according to the previous bound type definition Condition& Condition::rebind() { Object* o = access(); +#if 0 + const IOV* i = o->iov; + const IOVType* t = i->iovType; + i->fromString(o->validity); + if ( t != i->iovType ) { + except("Condition","Rebinding condition with different IOV types [%d <> %d] is not allowed!", + t ? t->type : -1, i->iovType ? i->iovType->type : -1); + } +#endif o->data.fromString(o->value); - //o->iov->fromString(o->validity); printout(INFO,"Condition","+++ condition:%s : %s rebinding value:%s", detector().path().c_str(), name().c_str(), o->value.c_str()); return *this; diff --git a/DDCore/src/ConditionsInterna.cpp b/DDCore/src/ConditionsInterna.cpp index 110190759..60daa05ac 100644 --- a/DDCore/src/ConditionsInterna.cpp +++ b/DDCore/src/ConditionsInterna.cpp @@ -74,7 +74,9 @@ void BlockData::bind(const BasicGrammar* g, void (*ctor)(void*,const void*), voi return; } else if ( grammar == g ) { - return; + // We cannot ingore secondary requests for data bindings. + // This leads to memory leaks in the caller! + except("Conditions","You may not bind conditions multiple times!"); } typeinfoCheck(grammar->type(),g->type(),"Conditions data blocks may not be assigned."); } diff --git a/DDCore/src/ConditonsTypes.cpp b/DDCore/src/ConditonsTypes.cpp index e09cba97b..d4400b34d 100644 --- a/DDCore/src/ConditonsTypes.cpp +++ b/DDCore/src/ConditonsTypes.cpp @@ -13,6 +13,7 @@ //========================================================================== // Framework include files +#include "DD4hep/Primitives.h" #include "DD4hep/objects/ConditionsInterna.h" #include "Math/Point3D.h" @@ -25,6 +26,7 @@ #include <list> #include <set> #include <map> +#include <deque> DD4HEP_DEFINE_CONDITIONS_U_CONT(char) DD4HEP_DEFINE_CONDITIONS_U_CONT(short) @@ -35,15 +37,9 @@ DD4HEP_DEFINE_CONDITIONS_U_CONT(long long) DD4HEP_DEFINE_CONDITIONS_CONT(bool) DD4HEP_DEFINE_CONDITIONS_CONT(float) DD4HEP_DEFINE_CONDITIONS_CONT(double) - -DD4HEP_DEFINE_CONDITIONS_TYPE(std::string) -DD4HEP_DEFINE_CONDITIONS_TYPE(std::vector<std::string>) -DD4HEP_DEFINE_CONDITIONS_TYPE(std::list<std::string>) -DD4HEP_DEFINE_CONDITIONS_TYPE(std::set<std::string>) +DD4HEP_DEFINE_CONDITIONS_CONT(std::string) // ROOT::Math Object instances -typedef std::map<std::string, int> map_string_int; -DD4HEP_DEFINE_CONDITIONS_TYPE(map_string_int) -DD4HEP_DEFINE_CONDITIONS_TYPE(ROOT::Math::XYZPoint) -DD4HEP_DEFINE_CONDITIONS_TYPE(ROOT::Math::XYZVector) -DD4HEP_DEFINE_CONDITIONS_TYPE(ROOT::Math::PxPyPzEVector) +DD4HEP_DEFINE_CONDITIONS_CONT(ROOT::Math::XYZPoint) +DD4HEP_DEFINE_CONDITIONS_CONT(ROOT::Math::XYZVector) +DD4HEP_DEFINE_CONDITIONS_CONT(ROOT::Math::PxPyPzEVector) diff --git a/DDCore/src/Primitives.cpp b/DDCore/src/Primitives.cpp index 680e18c8a..6ce9be8ed 100644 --- a/DDCore/src/Primitives.cpp +++ b/DDCore/src/Primitives.cpp @@ -152,10 +152,14 @@ std::string DD4hep::typeName(const std::type_info& typ) { return __typeinfoName(typ); } +/// Default destructor of specialized exception +DD4hep::invalid_handle_exception::~invalid_handle_exception() { +} + void DD4hep::invalidHandleError(const std::type_info& type) throw(std::exception) { - throw std::runtime_error("Attempt to access invalid object of type "+typeName(type)+" [Invalid Handle]"); + throw invalid_handle_exception("Attempt to access invalid object of type "+typeName(type)+" [Invalid Handle]"); } void DD4hep::invalidHandleAssignmentError(const std::type_info& from, @@ -167,7 +171,7 @@ void DD4hep::invalidHandleAssignmentError(const std::type_info& from, msg += " to "; msg += typeName(to); msg += " not possible!!"; - throw std::runtime_error(msg); + throw invalid_handle_exception(msg); } /// Throw exception when handles are check for validity @@ -186,6 +190,61 @@ void DD4hep::typeinfoCheck(const std::type_info& typ1, const std::type_info& typ } } +namespace DD4hep { + template<> const char* Primitive<bool>::default_format() { return "%d"; } + template<> const char* Primitive<char>::default_format() { return "%c"; } + template<> const char* Primitive<unsigned char>::default_format() { return "%02X"; } + template<> const char* Primitive<short>::default_format() { return "%d"; } + template<> const char* Primitive<unsigned short>::default_format() { return "%04X"; } + template<> const char* Primitive<int>::default_format() { return "%d"; } + template<> const char* Primitive<unsigned int>::default_format() { return "%08X"; } + template<> const char* Primitive<long>::default_format() { return "%ld"; } + template<> const char* Primitive<unsigned long>::default_format() { return "%016X"; } + template<> const char* Primitive<float>::default_format() { return "%f"; } + template<> const char* Primitive<double>::default_format() { return "%g"; } + template<> const char* Primitive<char*>::default_format() { return "%s"; } + template<> const char* Primitive<const char*>::default_format() { return "%s"; } + template<> const char* Primitive<std::string>::default_format() { return "%s"; } + + /// Generic function to convert to string + template <typename T> std::string Primitive<T>::toString(T value) { + char text[1024]; + ::snprintf(text,sizeof(text),default_format(),value); + return text; + } + + /// Convert string to string + template <> std::string Primitive<const char*>::toString(const char* value) { + if ( value ) { + return value; + } + throw std::runtime_error("Failed to convert (char*)NULL to std::string!"); + } + /// Convert string to string + template <> std::string Primitive<char*>::toString(char* value) { + if ( value ) { + return value; + } + throw std::runtime_error("Failed to convert (char*)NULL to std::string!"); + } + /// Convert string to string + template <> std::string Primitive<std::string>::toString(std::string value) { + return value; + } + + template std::string Primitive<bool>::toString(bool value); + template std::string Primitive<char>::toString(char value); + template std::string Primitive<unsigned char>::toString(unsigned char value); + template std::string Primitive<short>::toString(short value); + template std::string Primitive<unsigned short>::toString(unsigned short value); + template std::string Primitive<int>::toString(int value); + template std::string Primitive<unsigned int>::toString(unsigned int value); + template std::string Primitive<long>::toString(long value); + template std::string Primitive<unsigned long>::toString(unsigned long value); + template std::string Primitive<float>::toString(float value); + template std::string Primitive<double>::toString(double value); +} + /// Initializing Constructor DD4hep::ComponentCast::ComponentCast(const std::type_info& t, destroy_t d, cast_t c) : type(t), destroy(d), cast(c) { diff --git a/DDCore/src/parsers/GrammarsV2.h b/DDCore/src/parsers/GrammarsV2.h index 1b80b6e6a..ec0124876 100644 --- a/DDCore/src/parsers/GrammarsV2.h +++ b/DDCore/src/parsers/GrammarsV2.h @@ -23,6 +23,7 @@ //============================================================================== #include <string> #include <vector> +#include <deque> #include <list> #include <set> #include <map> @@ -208,7 +209,7 @@ namespace DD4hep { namespace Parsers { template <typename Iterator,typename InnerT,typename AllocatorT,typename Skipper> struct Grammar_<Iterator, std::vector<InnerT, AllocatorT>, Skipper > { typedef - VectorGrammar<Iterator, std::vector<InnerT, AllocatorT>,Skipper> + VectorGrammar<Iterator, std::vector<InnerT, AllocatorT>, Skipper> Grammar; }; // ---------------------------------------------------------------------------- @@ -217,16 +218,26 @@ namespace DD4hep { namespace Parsers { template <typename Iterator, typename InnerT, typename AllocatorT,typename Skipper> struct Grammar_<Iterator, std::list<InnerT, AllocatorT>, Skipper > { typedef - VectorGrammar<Iterator, std::list<InnerT, AllocatorT>,Skipper> + VectorGrammar<Iterator, std::list<InnerT, AllocatorT>, Skipper> Grammar; }; // ---------------------------------------------------------------------------- // Register VectorGrammar for std::set: // ---------------------------------------------------------------------------- - template <typename Iterator, typename InnerT, typename CompareT,typename AllocatorT, typename Skipper> + template <typename Iterator, typename InnerT, typename CompareT, typename AllocatorT, typename Skipper> struct Grammar_<Iterator, std::set<InnerT, CompareT, AllocatorT>, Skipper > { typedef - VectorGrammar<Iterator, std::set<InnerT, CompareT, AllocatorT>,Skipper> + VectorGrammar<Iterator, std::set<InnerT, CompareT, AllocatorT>, Skipper> + Grammar; + }; + + // ---------------------------------------------------------------------------- + // Register VectorGrammar for std::set: + // ---------------------------------------------------------------------------- + template <typename Iterator, typename InnerT, typename AllocatorT, typename Skipper> + struct Grammar_<Iterator, std::deque<InnerT, AllocatorT>, Skipper > { + typedef + VectorGrammar<Iterator, std::deque<InnerT, AllocatorT>, Skipper> Grammar; }; @@ -270,6 +281,7 @@ namespace DD4hep { namespace Parsers { //ph::function<Operations> op; // ---------------------------------------------------------------------------- }; // END PairGrammar + // ---------------------------------------------------------------------------- // Register PairGrammar: // ---------------------------------------------------------------------------- @@ -279,6 +291,7 @@ namespace DD4hep { namespace Parsers { { typedef PairGrammar<Iterator, std::pair<KeyT, ValueT>, Skipper> Grammar; }; + // ============================================================================ template< typename Iterator, typename MapT, typename Skipper> struct MapGrammar : qi::grammar<Iterator,MapT(), Skipper> { diff --git a/DDCore/src/parsers/ParsersObjects.cpp b/DDCore/src/parsers/ParsersObjects.cpp deleted file mode 100644 index 9114a035a..000000000 --- a/DDCore/src/parsers/ParsersObjects.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// $Id: $ -//========================================================================== -// AIDA Detector description implementation for LCD -//-------------------------------------------------------------------------- -// 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. -// -//========================================================================== -//========================================================================== -// Include files -//========================================================================== -#include "ParsersFactory.h" -#include "DD4hep/ToStream.h" - -using namespace std; -namespace ROOT { - namespace Math { - static bool operator<(const XYZPoint& a, const XYZPoint& b) { - if ( a.X() < b.X() ) return true; - if ( a.Y() < b.Y() ) return true; - if ( a.Z() < b.Z() ) return true; - return false; - } - static bool operator<(const XYZVector& a, const XYZVector& b) { - if ( a.X() < b.X() ) return true; - if ( a.Y() < b.Y() ) return true; - if ( a.Z() < b.Z() ) return true; - return false; - } - static bool operator<(const PxPyPzEVector& a, const PxPyPzEVector& b) { - if ( a.X() < b.X() ) return true; - if ( a.Y() < b.Y() ) return true; - if ( a.Z() < b.Z() ) return true; - if ( a.T() < b.T() ) return true; - return false; - } - } -} -// ============================================================================ -namespace DD4hep { - namespace Parsers { - // ========================================================================== - template<typename T1, typename T2> inline int - parse_(ROOT::Math::PositionVector3D<T1,T2>& result, const string& input){ - Skipper skipper; - typename Grammar_<IteratorT,ROOT::Math::PositionVector3D<T1,T2>,Skipper>::Grammar g; - IteratorT iter = input.begin(), end = input.end(); - if (qi::phrase_parse( iter, end, g, skipper, result)){ - return 1; - } - return 0; - } - // ========================================================================== - int parse(ROOT::Math::XYZPoint& result,const string& input) { - return parse_(result, input); - } - // ========================================================================== - /* parse 3D-vector - * @param result (output) the parsed vector - * @param input (input) the input string - * @return status code - * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl - * @date 2009-09-05 - */ - int parse(ROOT::Math::XYZVector& result,const string& input) { - ROOT::Math::XYZPoint point; - int sc = parse(point,input); - if ( 0 == sc ){ return sc; } // RETURN - result = point; - return 1; - } - int parse(ROOT::Math::PxPyPzEVector& result, const string& input) { - return parse_(result, input); - } - - // ========================================================================== - /* parse the vector of points - * @param resut (OUTPUT) the parser vector - * @param input (INPIUT) the string to be parsed - * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl - * @date 2009-09-05 - */ - // ========================================================================== - int parse(vector<ROOT::Math::XYZPoint>& result, const string& input) { - result.clear(); - return parse_(result, input); - } - int parse(list<ROOT::Math::XYZPoint>& result, const string& input) { - result.clear(); - return parse_(result, input); - } - int parse(set<ROOT::Math::XYZPoint>& result, const string& input) { - result.clear(); - return parse_(result, input); - } - // ========================================================================== - /* parse the vector of vectors - * @param resut (OUTPUT) the parser vector - * @param input (INPIUT) the string to be parsed - * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl - * @date 2009-09-05 - */ - // ========================================================================== - int parse(vector<ROOT::Math::XYZVector>& result, const string& input) { - result.clear(); - return parse_(result, input); - } - int parse(list<ROOT::Math::XYZVector>& result, const string& input) { - result.clear(); - return parse_(result, input); - } - int parse(set<ROOT::Math::XYZVector>& result, const string& input) { - result.clear(); - return parse_(result, input); - } - // ========================================================================== - /* parse the vector of vectors - * @param resut (OUTPUT) the parser vector - * @param input (INPIUT) the string to be parsed - * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl - * @date 2009-09-05 - */ - // ========================================================================== - int parse(vector<ROOT::Math::PxPyPzEVector>& result,const string& input) { - result.clear(); - return parse_(result, input); - } - int parse(list<ROOT::Math::PxPyPzEVector>& result,const string& input) { - result.clear(); - return parse_(result, input); - } - int parse(set<ROOT::Math::PxPyPzEVector>& result,const string& input) { - result.clear(); - return parse_(result, input); - } - - } -} diff --git a/DDCore/src/parsers/ParsersObjects_PxPyPzEVector.cpp b/DDCore/src/parsers/ParsersObjects_PxPyPzEVector.cpp new file mode 100644 index 000000000..ade021d61 --- /dev/null +++ b/DDCore/src/parsers/ParsersObjects_PxPyPzEVector.cpp @@ -0,0 +1,43 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +//========================================================================== +// Include files +//========================================================================== +#include "ParsersStandardListCommon.h" + +namespace ROOT { namespace Math { + bool operator<(const PxPyPzEVector& a, const PxPyPzEVector& b); + }} + +// ============================================================================ +namespace DD4hep { + namespace Parsers { + + int parse(ROOT::Math::PxPyPzEVector& result, const std::string& input) { + return parse_(result, input); + } + + // ========================================================================== + /* parse the vector of vectors + * @param resut (OUTPUT) the parser vector + * @param input (INPIUT) the string to be parsed + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-05 + */ + // ========================================================================== + IMPLEMENT_STL_PARSERS(ROOT::Math::PxPyPzEVector) + typedef ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<double> > _L; + IMPLEMENT_MAPPED_PARSERS(pair,_L) + } +} + + diff --git a/DDCore/src/parsers/ParsersObjects_XYZPoint.cpp b/DDCore/src/parsers/ParsersObjects_XYZPoint.cpp new file mode 100644 index 000000000..230369987 --- /dev/null +++ b/DDCore/src/parsers/ParsersObjects_XYZPoint.cpp @@ -0,0 +1,41 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +//========================================================================== +// Include files +//========================================================================== +#include "ParsersStandardListCommon.h" + +namespace ROOT { namespace Math { + bool operator<(const XYZPoint& a, const XYZPoint& b); + }} +// ============================================================================ +namespace DD4hep { + namespace Parsers { + + // ========================================================================== + int parse(ROOT::Math::XYZPoint& result,const std::string& input) { + return parse_(result, input); + } + // ========================================================================== + /* parse the vector of points + * @param resut (OUTPUT) the parser vector + * @param input (INPIUT) the string to be parsed + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-05 + */ + // ========================================================================== + IMPLEMENT_STL_PARSERS(ROOT::Math::XYZPoint) + IMPLEMENT_MAPPED_PARSERS(pair,ROOT::Math::XYZPoint) + } +} + + diff --git a/DDCore/src/parsers/ParsersObjects_XYZVector.cpp b/DDCore/src/parsers/ParsersObjects_XYZVector.cpp new file mode 100644 index 000000000..859ad9acf --- /dev/null +++ b/DDCore/src/parsers/ParsersObjects_XYZVector.cpp @@ -0,0 +1,54 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +//========================================================================== +// Include files +//========================================================================== +#include "ParsersStandardListCommon.h" + +namespace ROOT { namespace Math { + bool operator<(const XYZVector& a, const XYZVector& b); + }} + +// ============================================================================ +namespace DD4hep { + namespace Parsers { + + // ========================================================================== + /* parse 3D-vector + * @param result (output) the parsed vector + * @param input (input) the input string + * @return status code + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-05 + */ + int parse(ROOT::Math::XYZVector& result,const std::string& input) { + ROOT::Math::XYZPoint point; + int sc = parse(point,input); + if ( 0 == sc ){ return sc; } // RETURN + result = point; + return 1; + } + + // ========================================================================== + /* parse the vector of vectors + * @param resut (OUTPUT) the parser vector + * @param input (INPIUT) the string to be parsed + * @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl + * @date 2009-09-05 + */ + // ========================================================================== + IMPLEMENT_STL_PARSERS(ROOT::Math::XYZVector) + IMPLEMENT_MAPPED_PARSERS(pair,ROOT::Math::XYZVector) + } +} + + diff --git a/DDCore/src/parsers/ParsersStandardListCommon.h b/DDCore/src/parsers/ParsersStandardListCommon.h index d5f15c1eb..13841aee2 100644 --- a/DDCore/src/parsers/ParsersStandardListCommon.h +++ b/DDCore/src/parsers/ParsersStandardListCommon.h @@ -15,15 +15,55 @@ // Include files // ============================================================================ #include "DD4hep/Parsers.h" +#include "DD4hep/ToStream.h" #include "ParsersFactory.h" + +#define IMPLEMENT_MAPPED_PARSERS(type,X) \ + int parse(std::type <int,X>& result,const std::string& input) \ + { return parse_(result, input); } \ + int parse(std::type <unsigned long,X>& result,const std::string& input) \ + { return parse_(result, input); } \ + int parse(std::type <std::string,X>& result,const std::string& input) \ + { return parse_(result, input); } + +#define IMPLEMENT_STL_PARSER(x,y) \ + int parse(x < y > & result, const std::string& input) \ + { result.clear(); return parse_(result, input); } + +#define IMPLEMENT_STL_MAP_PARSER(x,k,v) \ + int parse(x < k, v > & result, const std::string& input) \ + { result.clear(); return parse_(result, input); } + +#define IMPLEMENT_STL_PARSERS(x) \ + IMPLEMENT_STL_PARSER(std::vector,x) \ + IMPLEMENT_STL_PARSER(std::list,x) \ + IMPLEMENT_STL_PARSER(std::set,x) \ + IMPLEMENT_STL_PARSER(std::deque,x) \ + IMPLEMENT_STL_MAP_PARSER(std::map,int,x) \ + IMPLEMENT_STL_MAP_PARSER(std::map,unsigned long,x) \ + IMPLEMENT_STL_MAP_PARSER(std::map,std::string,x) + // ============================================================================ -#define PARSERS_DEF_FOR_LIST(InnerType) \ - int DD4hep::Parsers::parse(std::vector<InnerType>& result,const std::string& input) \ - { return DD4hep::Parsers::parse_(result, input); } \ - int DD4hep::Parsers::parse(std::list<InnerType>& result,const std::string& input) \ - { return DD4hep::Parsers::parse_(result, input); } \ - int DD4hep::Parsers::parse(std::set<InnerType>& result,const std::string& input) \ - { return DD4hep::Parsers::parse_(result, input); } \ +#define PARSERS_DEF_FOR_LIST(InnerType) \ + namespace DD4hep{ namespace Parsers{ \ + IMPLEMENT_STL_PARSERS(InnerType) \ + IMPLEMENT_MAPPED_PARSERS(pair,InnerType) }} +// ============================================================================ +namespace DD4hep { + namespace Parsers { + // ======================================================================== + template<typename T1, typename T2> inline int + parse_(ROOT::Math::PositionVector3D<T1,T2>& result, const std::string& input){ + Skipper skipper; + typename Grammar_<IteratorT,ROOT::Math::PositionVector3D<T1,T2>,Skipper>::Grammar g; + IteratorT iter = input.begin(), end = input.end(); + if (qi::phrase_parse( iter, end, g, skipper, result)){ + return 1; + } + return 0; + } + } +} // ============================================================================ #endif /* PARSERS_STANDARD_LIST_COMMON_H */ diff --git a/DDCore/src/parsers/ParsersStandardList_bool.cpp b/DDCore/src/parsers/ParsersStandardList_bool.cpp new file mode 100644 index 000000000..45e356964 --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_bool.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(bool) diff --git a/DDCore/src/parsers/ParsersStandardList_char.cpp b/DDCore/src/parsers/ParsersStandardList_char.cpp new file mode 100644 index 000000000..7c03fe3b2 --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_char.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(char) diff --git a/DDCore/src/parsers/ParsersStandardList_double.cpp b/DDCore/src/parsers/ParsersStandardList_double.cpp new file mode 100644 index 000000000..f5b02988c --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_double.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(double) diff --git a/DDCore/src/parsers/ParsersStandardList_float.cpp b/DDCore/src/parsers/ParsersStandardList_float.cpp new file mode 100644 index 000000000..441c5e1ff --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_float.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(float) diff --git a/DDCore/src/parsers/ParsersStandardList_int.cpp b/DDCore/src/parsers/ParsersStandardList_int.cpp new file mode 100644 index 000000000..c1d57cf1f --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_int.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(int) diff --git a/DDCore/src/parsers/ParsersStandardList_long.cpp b/DDCore/src/parsers/ParsersStandardList_long.cpp new file mode 100644 index 000000000..1e47ee53c --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_long.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(long) diff --git a/DDCore/src/parsers/ParsersStandardList4.cpp b/DDCore/src/parsers/ParsersStandardList_longdouble.cpp similarity index 85% rename from DDCore/src/parsers/ParsersStandardList4.cpp rename to DDCore/src/parsers/ParsersStandardList_longdouble.cpp index 582156cef..04dafe3ff 100644 --- a/DDCore/src/parsers/ParsersStandardList4.cpp +++ b/DDCore/src/parsers/ParsersStandardList_longdouble.cpp @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -10,7 +10,4 @@ // //========================================================================== #include "ParsersStandardListCommon.h" -PARSERS_DEF_FOR_LIST(double) -PARSERS_DEF_FOR_LIST(float) PARSERS_DEF_FOR_LIST(long double) -PARSERS_DEF_FOR_LIST(std::string) diff --git a/DDCore/src/parsers/ParsersStandardList_longlong.cpp b/DDCore/src/parsers/ParsersStandardList_longlong.cpp new file mode 100644 index 000000000..a53fee383 --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_longlong.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(long long) diff --git a/DDCore/src/parsers/ParsersStandardList_short.cpp b/DDCore/src/parsers/ParsersStandardList_short.cpp new file mode 100644 index 000000000..5193f077b --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_short.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(short) diff --git a/DDCore/src/parsers/ParsersStandardList_signedchar.cpp b/DDCore/src/parsers/ParsersStandardList_signedchar.cpp new file mode 100644 index 000000000..2aba868da --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_signedchar.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(signed char) diff --git a/DDCore/src/parsers/ParsersStandardList1.cpp b/DDCore/src/parsers/ParsersStandardList_uchar.cpp similarity index 85% rename from DDCore/src/parsers/ParsersStandardList1.cpp rename to DDCore/src/parsers/ParsersStandardList_uchar.cpp index e2d15fd18..8682082b6 100644 --- a/DDCore/src/parsers/ParsersStandardList1.cpp +++ b/DDCore/src/parsers/ParsersStandardList_uchar.cpp @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -10,7 +10,4 @@ // //========================================================================== #include "ParsersStandardListCommon.h" -PARSERS_DEF_FOR_LIST(bool) -PARSERS_DEF_FOR_LIST(char) PARSERS_DEF_FOR_LIST(unsigned char) -PARSERS_DEF_FOR_LIST(signed char) diff --git a/DDCore/src/parsers/ParsersStandardList_uint.cpp b/DDCore/src/parsers/ParsersStandardList_uint.cpp new file mode 100644 index 000000000..668c8dfd5 --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_uint.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(unsigned int) diff --git a/DDCore/src/parsers/ParsersStandardList_ulong.cpp b/DDCore/src/parsers/ParsersStandardList_ulong.cpp new file mode 100644 index 000000000..093e6a1b0 --- /dev/null +++ b/DDCore/src/parsers/ParsersStandardList_ulong.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(unsigned long) diff --git a/DDCore/src/parsers/ParsersStandardList3.cpp b/DDCore/src/parsers/ParsersStandardList_ulonglong.cpp similarity index 84% rename from DDCore/src/parsers/ParsersStandardList3.cpp rename to DDCore/src/parsers/ParsersStandardList_ulonglong.cpp index ca60ff573..39830e971 100644 --- a/DDCore/src/parsers/ParsersStandardList3.cpp +++ b/DDCore/src/parsers/ParsersStandardList_ulonglong.cpp @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -10,7 +10,4 @@ // //========================================================================== #include "ParsersStandardListCommon.h" -PARSERS_DEF_FOR_LIST(long) -PARSERS_DEF_FOR_LIST(unsigned long) -PARSERS_DEF_FOR_LIST(long long) PARSERS_DEF_FOR_LIST(unsigned long long) diff --git a/DDCore/src/parsers/ParsersStandardList2.cpp b/DDCore/src/parsers/ParsersStandardList_ushort.cpp similarity index 85% rename from DDCore/src/parsers/ParsersStandardList2.cpp rename to DDCore/src/parsers/ParsersStandardList_ushort.cpp index b4efd54bd..b7da7bad1 100644 --- a/DDCore/src/parsers/ParsersStandardList2.cpp +++ b/DDCore/src/parsers/ParsersStandardList_ushort.cpp @@ -1,4 +1,4 @@ -// $Id: $ +// $Id$ //========================================================================== // AIDA Detector description implementation for LCD //-------------------------------------------------------------------------- @@ -10,7 +10,4 @@ // //========================================================================== #include "ParsersStandardListCommon.h" -PARSERS_DEF_FOR_LIST(int) -PARSERS_DEF_FOR_LIST(short) PARSERS_DEF_FOR_LIST(unsigned short) -PARSERS_DEF_FOR_LIST(unsigned int) diff --git a/DDCore/src/parsers/ParsersStandardMisc1.cpp b/DDCore/src/parsers/ParsersStandardMisc1.cpp index 288894e94..3af30b632 100644 --- a/DDCore/src/parsers/ParsersStandardMisc1.cpp +++ b/DDCore/src/parsers/ParsersStandardMisc1.cpp @@ -15,10 +15,6 @@ int DD4hep::Parsers::parse(std::pair<double,double>& result, const std::string& return DD4hep::Parsers::parse_(result, input); } -int DD4hep::Parsers::parse(std::pair<int, int>& result, const std::string& input) { - return DD4hep::Parsers::parse_(result, input); -} - int DD4hep::Parsers::parse(std::vector<std::pair<double, double> >& result, const std::string& input) { return DD4hep::Parsers::parse_(result, input); } diff --git a/DDCore/src/parsers/ParsersStandardMisc2.cpp b/DDCore/src/parsers/ParsersStandardMisc2.cpp index 01fc42f96..bab51bb23 100644 --- a/DDCore/src/parsers/ParsersStandardMisc2.cpp +++ b/DDCore/src/parsers/ParsersStandardMisc2.cpp @@ -14,15 +14,3 @@ int DD4hep::Parsers::parse(std::vector<std::vector<double> >& result, const std::string& input) { return DD4hep::Parsers::parse_(result, input); } - -int DD4hep::Parsers::parse(std::map<int, int>& result, const std::string& input) { - return DD4hep::Parsers::parse_(result, input); -} - -int DD4hep::Parsers::parse(std::map<int, double>& result, const std::string& input) { - return DD4hep::Parsers::parse_(result, input); -} - -int DD4hep::Parsers::parse(std::map<std::string, std::string>& result, const std::string& input) { - return DD4hep::Parsers::parse_(result, input); -} diff --git a/DDCore/src/parsers/ParsersStandardMisc3.cpp b/DDCore/src/parsers/ParsersStandardMisc3.cpp index f56a87a16..873302446 100644 --- a/DDCore/src/parsers/ParsersStandardMisc3.cpp +++ b/DDCore/src/parsers/ParsersStandardMisc3.cpp @@ -11,18 +11,6 @@ //========================================================================== #include "ParsersStandardMiscCommon.h" -int DD4hep::Parsers::parse(std::map<std::string, int>& result, const std::string& input) { - return DD4hep::Parsers::parse_(result, input); -} - -int DD4hep::Parsers::parse(std::map<std::string, unsigned int>& result, const std::string& input) { - return DD4hep::Parsers::parse_(result, input); -} - -int DD4hep::Parsers::parse(std::map<std::string, double>& result, const std::string& input) { - return DD4hep::Parsers::parse_(result, input); -} - int DD4hep::Parsers::parse(std::map<std::string, std::vector<std::string> >& result, const std::string& input) { return DD4hep::Parsers::parse_(result, input); } diff --git a/DDCore/src/parsers/ParsersStandardMisc4.cpp b/DDCore/src/parsers/ParsersStandardMisc4.cpp index be09c833a..d1908c61b 100644 --- a/DDCore/src/parsers/ParsersStandardMisc4.cpp +++ b/DDCore/src/parsers/ParsersStandardMisc4.cpp @@ -18,7 +18,3 @@ int DD4hep::Parsers::parse(std::map<std::string, std::vector<int> >& result, con int DD4hep::Parsers::parse(std::map<std::string, std::vector<double> >& result, const std::string& input) { return DD4hep::Parsers::parse_(result, input); } - -int DD4hep::Parsers::parse(std::map<int, std::string>& result, const std::string& input) { - return DD4hep::Parsers::parse_(result, input); -} diff --git a/DDCore/src/parsers/ParsersStandard_string.cpp b/DDCore/src/parsers/ParsersStandard_string.cpp new file mode 100644 index 000000000..a1a039621 --- /dev/null +++ b/DDCore/src/parsers/ParsersStandard_string.cpp @@ -0,0 +1,13 @@ +// $Id$ +//========================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------------- +// 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. +// +//========================================================================== +#include "ParsersStandardListCommon.h" +PARSERS_DEF_FOR_LIST(std::string) diff --git a/DDG4/examples/SiDSim.py b/DDG4/examples/SiDSim.py index b08d81d9f..022a3de9e 100644 --- a/DDG4/examples/SiDSim.py +++ b/DDG4/examples/SiDSim.py @@ -87,6 +87,7 @@ def run(): gen.Particle = 'pi+' gen.Energy = 100 * GeV gen.Multiplicity = 2 + gen.Distribution = 'cos(theta)' kernel.generatorAction().adopt(gen) print "# Install vertex smearing for this interaction" gen = DDG4.GeneratorAction(kernel,"Geant4InteractionVertexSmear/SmearPi+"); @@ -101,6 +102,7 @@ def run(): gen.Particle = 'e-' gen.Energy = 25 * GeV gen.Multiplicity = 3 + gen.Distribution = 'uniform' kernel.generatorAction().adopt(gen) print " Install vertex smearing for this interaction" gen = DDG4.GeneratorAction(kernel,"Geant4InteractionVertexSmear/SmearE-"); diff --git a/DDG4/include/DDG4/Geant4IsotropeGenerator.h b/DDG4/include/DDG4/Geant4IsotropeGenerator.h index 413f35003..9cd295112 100644 --- a/DDG4/include/DDG4/Geant4IsotropeGenerator.h +++ b/DDG4/include/DDG4/Geant4IsotropeGenerator.h @@ -31,6 +31,8 @@ namespace DD4hep { */ class Geant4IsotropeGenerator: public Geant4ParticleGenerator { protected: + /// Property: Distribution name. Default: "uniform". Allowed: "uniform", "cos(theta)", "ffbar", "eta" + std::string m_distribution; /// Property: Minimal phi angular value double m_phiMin; /// Property: Maximal phi angular value @@ -39,12 +41,20 @@ namespace DD4hep { double m_thetaMin; /// Property: Maximal theta angular value double m_thetaMax; - + /// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = m_energy) /** Use this function to implement isotrop guns, multiple guns etc. User must return a UNIT vector, which gets scaled with momentum. */ virtual void getParticleDirection(int num, ROOT::Math::XYZVector& direction, double& momentum) const; + /// e+e- --> ffbar particle distribution ~ 1 + cos^2(theta) + void getParticleDirectionFFbar(int num, ROOT::Math::XYZVector& direction, double& momentum) const; + /// e+e- --> ffbar particle distribution ~ 1 + cos^2(theta) + void getParticleDirectionEta(int num, ROOT::Math::XYZVector& direction, double& momentum) const; + /// Particle distribution ~ cos(theta) + void getParticleDirectionCosTheta(int num, ROOT::Math::XYZVector& direction, double& momentum) const; + /// Uniform particle distribution + void getParticleDirectionUniform(int num, ROOT::Math::XYZVector& direction, double& momentum) const; public: /// Standard constructor diff --git a/DDG4/python/DDG4.py b/DDG4/python/DDG4.py index ddd15b288..f1aff5f85 100644 --- a/DDG4/python/DDG4.py +++ b/DDG4/python/DDG4.py @@ -469,7 +469,7 @@ class Geant4: def printDetectors(self): print '+++ List of sensitive detectors:' for i in self.lcdd.detectors(): - print i.second.ptr().GetName() + #print i.second.ptr().GetName() o = DetElement(i.second.ptr()) sd = self.lcdd.sensitiveDetector(o.name()) if sd.isValid(): diff --git a/DDG4/src/Geant4IsotropeGenerator.cpp b/DDG4/src/Geant4IsotropeGenerator.cpp index c49712656..d8b116048 100644 --- a/DDG4/src/Geant4IsotropeGenerator.cpp +++ b/DDG4/src/Geant4IsotropeGenerator.cpp @@ -30,6 +30,7 @@ Geant4IsotropeGenerator::Geant4IsotropeGenerator(Geant4Context* ctxt, const stri declareProperty("PhiMax", m_phiMax = 2.0*M_PI); declareProperty("ThetaMin", m_thetaMin = 0.0); declareProperty("ThetaMax", m_thetaMax = M_PI); + declareProperty("Distribution", m_distribution = "uniform" ); } /// Default destructor @@ -37,8 +38,8 @@ Geant4IsotropeGenerator::~Geant4IsotropeGenerator() { InstanceCount::decrement(this); } -/// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = m_energy) -void Geant4IsotropeGenerator::getParticleDirection(int, ROOT::Math::XYZVector& direction, double& momentum) const { +/// Uniform particle distribution +void Geant4IsotropeGenerator::getParticleDirectionUniform(int, ROOT::Math::XYZVector& direction, double& momentum) const { Geant4Event& evt = context()->event(); Geant4Random& rnd = evt.random(); double phi = m_phiMin+(m_phiMax-m_phiMin)*rnd.rndm(); @@ -50,3 +51,84 @@ void Geant4IsotropeGenerator::getParticleDirection(int, ROOT::Math::XYZVector& d direction.SetXYZ(x1,x2,x3); momentum = rnd.rndm()*momentum; } + +/// Particle distribution ~ cos(theta) +void Geant4IsotropeGenerator::getParticleDirectionCosTheta(int, ROOT::Math::XYZVector& direction, double& momentum) const { + Geant4Event& evt = context()->event(); + Geant4Random& rnd = evt.random(); + double phi = m_phiMin+(m_phiMax-m_phiMin)*rnd.rndm(); + double cos_theta = std::cos(m_thetaMin)+(std::cos(m_thetaMax)-std::cos(m_thetaMin))*rnd.rndm(); + double sin_theta = std::sqrt(1.0-cos_theta*cos_theta); + double x1 = sin_theta*std::cos(phi); + double x2 = sin_theta*std::sin(phi); + double x3 = cos_theta; + + direction.SetXYZ(x1,x2,x3); + momentum = rnd.rndm()*momentum; +} + +/// Particle distribution flat in eta (pseudo rapidity) +void Geant4IsotropeGenerator::getParticleDirectionEta(int, ROOT::Math::XYZVector& direction, double& momentum) const { + Geant4Event& evt = context()->event(); + Geant4Random& rnd = evt.random(); + // See https://en.wikipedia.org/wiki/Pseudorapidity + double phi = m_phiMin+(m_phiMax-m_phiMin)*rnd.rndm(); + double eta_min = -1.0*std::log(std::tan(m_thetaMin/2.0)); + double eta_max = -1.0*std::log(std::tan(m_thetaMax/2.0)); + double eta = eta_min + (eta_max-eta_min)*rnd.rndm(); + double x1 = std::cos(phi); + double x2 = std::sin(phi); + double x3 = std::sinh(eta); + double r = std::sqrt(1.0+x3*x3); + direction.SetXYZ(x1/r,x2/r,x3/r); + momentum = rnd.rndm()*momentum; +} + +/// e+e- --> ffbar particle distribution ~ 1 + cos^2(theta) +void Geant4IsotropeGenerator::getParticleDirectionFFbar(int, ROOT::Math::XYZVector& direction, double& momentum) const { + struct Distribution { + static double ffbar(double x) { double c = std::cos(x); return 1 + c*c; } + //static double integral(double x) { return 1.5*x + sin(2.*x)/4.0; } + }; + Geant4Event& evt = context()->event(); + Geant4Random& rnd = evt.random(); + double phi = m_phiMin+(m_phiMax-m_phiMin)*rnd.rndm(); + + // 1 + cos^2(theta) cannot be integrated and then inverted. + // We have to throw the dice until it fits..... + double v1 = Distribution::ffbar(m_thetaMin), v2 = Distribution::ffbar(m_thetaMax); + double vmax = std::max(v1,v2); // ffbar symmetric and monotonic in |x|. + while(1) { + double dice = rnd.rndm()*vmax; + double theta = m_thetaMin+(m_thetaMax-m_thetaMin)*rnd.rndm(); + double dist = Distribution::ffbar(theta); + if ( dice <= dist ) { + double x1 = std::sin(theta)*std::cos(phi); + double x2 = std::sin(theta)*std::sin(phi); + double x3 = std::cos(theta); + direction.SetXYZ(x1,x2,x3); + momentum = rnd.rndm()*momentum; + return; + } + } +} + +/// Particle modification. Caller presets defaults to: ( direction = m_direction, momentum = m_energy) +void Geant4IsotropeGenerator::getParticleDirection(int num, ROOT::Math::XYZVector& direction, double& momentum) const { + switch(::toupper(m_distribution[0])) { + case 'C': // cos(theta) + return getParticleDirectionCosTheta(num, direction, momentum); + case 'F': // ffbar: ~ 1 + cos^2(theta) + return getParticleDirectionFFbar(num, direction, momentum); + case 'E': // eta, rapidity, pseudorapidity + case 'P': + case 'R': + return getParticleDirectionEta(num, direction, momentum); + case 'U': // uniform + return getParticleDirectionUniform(num, direction, momentum); + default: + break; + } + except("Unknown distribution densitiy: %s. Cannot generate primaries.", + m_distribution.c_str()); +} diff --git a/doc/release.notes b/doc/release.notes index e43a1c782..85d1715e8 100644 --- a/doc/release.notes +++ b/doc/release.notes @@ -3,6 +3,14 @@ DD4hep ---- Release Notes ================================= +2016-03-03 M.Frank + - Improve/complete job options type palette. + - Allow modify the Geant4IsotropGenerator to shoot particle distributions according + to several distributions: + flat in : uniform, cos(theta), eta/pseudorapidity, ffbar (1+cos^2 theta) + Option: generator.Distribution = 'cos(theta)' + Default is uniform. + -------- | v00-15 | -------- -- GitLab