diff --git a/DDCond/CMakeLists.txt b/DDCond/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3d3d8be05e6166f49478c538aad35d5ac8b04d49 --- /dev/null +++ b/DDCond/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 2.8.0 FATAL_ERROR) +#--------------------------- +set( PackageName DDCond ) + +#---add additional packages here-------------------------------------------------- +if(NOT DD4HEP_BUILD_ALL) +find_package( DD4hep ) +endif() +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${DD4hep_ROOT}/cmake ) +include( DD4hep ) + +find_package( ROOT REQUIRED ) +#---Includedirs ------------------------------------------------------------------ +include_directories(${CMAKE_SOURCE_DIR}/DDCore/include + ${CMAKE_SOURCE_DIR}/DDSegmentation/include + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${DD4hep_INCLUDE_DIRS} + ${ROOT_INCLUDE_DIR} ) + +#---DD4hepCond library -------------------------------------------------------------- +file(GLOB sources src/*.cpp) +add_library(DD4hepCond SHARED ${sources}) +target_link_libraries(DD4hepCond DD4hepCore ${ROOT_LIBRARIES}) +SET( CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic -Wno-long-long") + + +if(DD4HEP_USE_XERCESC) + add_definitions(-DDD4HEP_USE_XERCESC) +else() + add_definitions(-DDD4HEP_USE_TINYXML) +endif() +SET_TARGET_PROPERTIES( DD4hepCond PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION}) +#---DD4hepCond rootmap -------------------------------------------------------------- +dd4hep_generate_rootmap(DD4hepCond) + +install(DIRECTORY include/DDCond + DESTINATION include + PATTERN ".svn" EXCLUDE ) + +install(TARGETS DD4hepCond + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ) +# to do: add corresponding uninstall... +#------------------------------------------------------- diff --git a/DDCond/include/DDCond/ConditionValidator.h b/DDCond/include/DDCond/ConditionValidator.h new file mode 100644 index 0000000000000000000000000000000000000000..7413544f412e86a3907b444d4b018a98d23698e0 --- /dev/null +++ b/DDCond/include/DDCond/ConditionValidator.h @@ -0,0 +1,48 @@ +// $Id: Readout.h 951 2013-12-16 23:37:56Z Christian.Grefe@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_GEOMETRY_CONDITIONVALIDATOR_H +#define DD4HEP_GEOMETRY_CONDITIONVALIDATOR_H + +// Framework includes +#include "DDCond/Condition.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +//DD4HEP_INSTANTIATE_HANDLE_NAMED(ConditionObject); + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /* + * Geometry namespace declaration + */ + namespace Geometry { + + /** @class ConditionValidator ConditionValidator.h DD4hep/ConditionValidator.h + * + * @author M.Frank + * @version 1.0 + */ + class ConditionValidator { + public: + + /// Standard constructor + ConditionValidator(); + /// Validate detector subtree and return conditions out of date + bool validate(DetElement subtree, std::vector<Condition>& tobe_updated); + + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_GEOMETRY_CONDITIONVALIDATOR_H */ diff --git a/DDCond/include/DDCond/ConditionsHandler.h b/DDCond/include/DDCond/ConditionsHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..815e6e0551976a16cabdb25b5802cb118e5d2123 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsHandler.h @@ -0,0 +1,76 @@ +// $Id: Geant4Setup.cpp 578 2013-05-17 22:33:09Z markus.frank $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_CONDITIONS_CONDITIONSHANDLER_H +#define DD4HEP_CONDITIONS_CONDITIONSHANDLER_H + +// Framework include files +#include "DDCond/ConditionsStack.h" + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /* + * Conditions namespace declaration + */ + namespace Geometry { + + /// Forward declarations + class ConditionsStack; + class LCDD; + + /** @class ConditionsHandler ConditionsHandler.h DDCond/ConditionsHandler.h + * + * Class caching all known conditions operations for one LCDD instance. + * Internally the instances are fragmented to subdetectors defined + * by the next-to-top level detector elements. + * + * + * @author M.Frank + * @version 1.0 + */ + class ConditionsHandler { + friend class LCDD; + + protected: + LCDD& m_lcdd; + /// Reference count + int m_refCount; + + protected: + /// Default constructor + ConditionsHandler(LCDD& lcdd); + /// Default destructor + virtual ~ConditionsHandler(); + /// Population entry: Apply a complete stack of ordered conditionss to the geometry structure + void apply(ConditionsStack& stack); + + public: + /// Create and install a new instance tree + static void install(LCDD& lcdd); + /// Unregister and delete a tree instance + static void uninstall(LCDD& lcdd); + + /// Functor callback + static void triggerUpdate(DetElement detector); + + /// Add reference count + int addRef(); + /// Release object. If reference count goes to NULL, automatic deletion is triggered. + int release(); + /// Open a new transaction stack (Note: only one stack allowed!) + void openTransaction(); + /// Close existing transaction stack and apply all conditionss + void closeTransaction(); + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_CONDITIONS_CONDITIONSHANDLER_H */ diff --git a/DDCond/include/DDCond/ConditionsOperators.h b/DDCond/include/DDCond/ConditionsOperators.h new file mode 100644 index 0000000000000000000000000000000000000000..9930b22bbd05b110bc24946456757a3bac891885 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsOperators.h @@ -0,0 +1,32 @@ +// $Id: XMLStack.h 889 2013-11-14 15:55:39Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_CONDITIONS_CONDITIONSOPERATORS_H +#define DD4HEP_CONDITIONS_CONDITIONSOPERATORS_H + +// Framework include files + + +// C/C++ include files + + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /* + * Geometry namespace declaration + */ + namespace Geometry { + + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_CONDITIONS_CONDITIONSOPERATORS_H */ diff --git a/DDCond/include/DDCond/ConditionsStack.h b/DDCond/include/DDCond/ConditionsStack.h new file mode 100644 index 0000000000000000000000000000000000000000..f0b5c408e93a6d748474cdd73c9178889a46f6c4 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsStack.h @@ -0,0 +1,78 @@ +// $Id: XMLStack.h 889 2013-11-14 15:55:39Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_CONDITIONS_CONDITIONSSTACK_H +#define DD4HEP_CONDITIONS_CONDITIONSSTACK_H + +// Framework include files +#include "DD4hep/Detector.h" + +// C/C++ include files +#include <memory> + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + /* + * Geometry namespace declaration + */ + namespace Geometry { + + // Forward declarations + namespace ConditionsInterna { + class Entry; + } + + /** @class ConditionsStack ConditionsStack.h DDCond/ConditionsStack.h + * + * The data class behind a conditions handle. + * + * @author M.Frank + * @version 1.0 + */ + class ConditionsStack { + public: + friend class std::auto_ptr<ConditionsStack>; + + typedef ConditionsInterna::Entry Entry; + typedef std::map<std::string,Entry*> Stack; + + protected: + /// The subdetector specific map of conditions caches + Stack m_stack; + + /// Standard constructor + ConditionsStack(); + /// Standard destructor + virtual ~ConditionsStack(); + + public: + /// Static client accessor + static ConditionsStack& get(); + /// Create an conditions stack instance. The creation of a second instance will be refused. + static void create(); + /// Check existence of conditions stack + static bool exists(); + /// Push new entry into the stack + void insert(std::auto_ptr<Entry>& data); + /// Clear data content and remove the slignment stack + void release(); + /// Access size of the conditions stack + size_t size() const { return m_stack.size(); } + /// Retrieve an conditions entry of the current stack + std::auto_ptr<Entry> pop(); + /// Get all path entries to be aligned. Note: transient! + std::vector<const Entry*> entries() const; + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ + +#endif /* DD4HEP_CONDITIONS_CONDITIONSSTACK_H */ diff --git a/DDCond/include/DDCond/ConditionsTags.h b/DDCond/include/DDCond/ConditionsTags.h new file mode 100644 index 0000000000000000000000000000000000000000..8b2b06a30f371bd2e88b9db55f3904e8fdc77655 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsTags.h @@ -0,0 +1,39 @@ +// $Id: XMLTags.h 889 2013-11-14 15:55:39Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_CONDITIONS_CONDITIONSTAGS_H +#define DD4HEP_CONDITIONS_CONDITIONSTAGS_H + +// Framework include files +#include "XML/XMLElements.h" +#ifndef UNICODE +#define UNICODE(x) extern const Tag_t Unicode_##x +#endif + +// Unicode tags known to the conditions section +namespace DD4hep { + namespace XML { + namespace Conditions { + UNICODE(conditions); + UNICODE(detelements); + UNICODE(detelement); + UNICODE(temperature); + UNICODE(pressure); + UNICODE(path); + UNICODE(validity); + UNICODE(open_transaction); + UNICODE(close_transaction); + } + // User must ensure there are no clashes. If yes, then the clashing entry is unnecessary. + using namespace DD4hep::XML::Conditions; + } +} + +#undef UNICODE // Do not miss this one! +#include "XML/XMLTags.h" +#endif /* DD4HEP_CONDITIONS_CONDITIONSTAGS_H */ diff --git a/DDCond/include/DDCond/ConditionsTransaction.h b/DDCond/include/DDCond/ConditionsTransaction.h new file mode 100644 index 0000000000000000000000000000000000000000..5a0bebd4a014b731ab856dafe243b0b9069387d1 --- /dev/null +++ b/DDCond/include/DDCond/ConditionsTransaction.h @@ -0,0 +1,55 @@ +// $Id: Geant4Setup.cpp 578 2013-05-17 22:33:09Z markus.frank $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#ifndef DD4HEP_CONDITIONS_CONDITIONSTRANSACTION_H +#define DD4HEP_CONDITIONS_CONDITIONSTRANSACTION_H + +// Framework include files +#include "DD4hep/Primitives.h" + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + namespace XML { class Handle_t; } + + /* + * Conditions namespace declaration + */ + namespace Geometry { + + // Forward declarations + class LCDD; + class ConditionsHandler; + + /** @class ConditionsTransaction + * + * Manage conditions transaction to the handler for a given LCDD instance + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ + struct ConditionsTransaction { + /// Internal flag to remember transaction contexts + bool flag; + /// Reference to the current LCDD instance + LCDD& lcdd; + /// Reference to the conditions handler + ConditionsHandler* m_handler; + + /// Default constructor + ConditionsTransaction(LCDD& l, const XML::Handle_t& e); + /// Default destructor + ~ConditionsTransaction(); + }; + + } /* End namespace Geometry */ +} /* End namespace DD4hep */ +#endif /* DD4HEP_CONDITIONS_CONDITIONSTRANSACTION_H */ diff --git a/DDCond/src/ConditionTest.cpp b/DDCond/src/ConditionTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..73e320801be69903c2265c1d7acc648564faaa2a --- /dev/null +++ b/DDCond/src/ConditionTest.cpp @@ -0,0 +1,114 @@ +// $Id: Readout.h 951 2013-12-16 23:37:56Z Christian.Grefe@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DD4hep/Printout.h" +#include "DD4hep/Conditions.h" +#include "DD4hep/DetFactoryHelper.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +namespace { + + /// Dump the conditions of one detectpr element + void dump_element(DetElement elt) { + string test = "ConditionsTest1"; + Conditions conds = elt.conditions(); + printout(INFO,test,"DetElement:%s # of conditons:%d",elt.path().c_str(),int(conds.count())); + const Conditions::Entries& entries = conds.entries(); + for(Conditions::Entries::const_iterator i=entries.begin(); i!=entries.end(); ++i) { + Condition c((*i).second); + string type = c.type(); + printout(INFO,test," %s Condition[%s]: %s [%s] Validity:%s", + c.detector().path().c_str(), type.c_str(), c.name().c_str(), + c.value().c_str(), c.validity().c_str()); + + if ( type == "alignment" ) { + c.bind<string>(); + } + else if ( type == "temperature" ) { + c.bind<double>(); + printout(INFO,test," %s : double value:%g ", + c.name().c_str(), c.get<double>()); + } + else if ( type == "pressure" ) { + c.bind<double>(); + printout(INFO,test," %s : double value:%g [%g hPa]", + c.name().c_str(), c.get<double>(), + _multiply(c.get<double>(),"1.0/hPa")); + } + else if ( type == "whatever" ) { + c.bind<vector<double> >(); + const vector<double>& v = c.get<vector<double> >(); + printout(INFO,test," %s : vector<double> size:%d = %s", + c.name().c_str(), int(v.size()), c.block().str().c_str()); + } + printout(INFO,test, " Type: %s",typeName(c.typeInfo()).c_str()); + } + } + + /// Dump conditions tree of a detector element + void dump_conditions(DetElement elt) { + Conditions conds = elt.conditions(); + const DetElement::Children& children = elt.children(); + if ( !conds.isValid() ) + printout(INFO,"ConditionsTest1","DetElement:%s NO CONDITIONS present",elt.path().c_str()); + else + dump_element(elt); + for(DetElement::Children::const_iterator j=children.begin(); j!=children.end(); ++j) + dump_conditions((*j).second); + } + + /// Test execution function + long conditions_test(LCDD& lcdd, int argc, char** argv) { + DetElement det = lcdd.world(); + string args = ""; + for(int i=0; i<argc; ++i) { args += argv[i], args += " "; }; + printout(INFO,"ConditionsTest1","Args: %s",args.c_str()); + dump_conditions(det); + return 1; + } +} + +DECLARE_APPLY(ConditionsTest1,conditions_test) + + +namespace { + + struct Callee { + void call(unsigned int tags, DetElement& det, void* param) { + if ( DetElement::CONDITIONS_CHANGED == (tags&DetElement::CONDITIONS_CHANGED) ) + printout(INFO,"Callee","+++ Conditions update %s param:%p",det.path().c_str(),param); + if ( DetElement::PLACEMENT_CHANGED == (tags&DetElement::PLACEMENT_CHANGED) ) + printout(INFO,"Callee","+++ Alignment update %s param:%p",det.path().c_str(),param); + } + }; + + /// Callback conditions tree of a detector element + void callback_install(DetElement elt, Callee* c) { + Position local, global; + const DetElement::Children& children = elt.children(); + elt.localToWorld(local, global); + elt.callAtUpdate(DetElement::CONDITIONS_CHANGED|DetElement::PLACEMENT_CHANGED,c,&Callee::call); + for(DetElement::Children::const_iterator j=children.begin(); j!=children.end(); ++j) + callback_install((*j).second,c); + } + + /// Test execution function + long callback_test(LCDD& lcdd, int /* argc */, char** /* argv */) { + DetElement det = lcdd.world(); + callback_install(det, new Callee()); + return 1; + } +} + +DECLARE_APPLY(CallbackInstallTest,callback_test) diff --git a/DDCond/src/ConditionValidator.cpp b/DDCond/src/ConditionValidator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ecbee67cdb28da2b5fb7c0c9303dbfb7aef52e2 --- /dev/null +++ b/DDCond/src/ConditionValidator.cpp @@ -0,0 +1,27 @@ +// $Id: Readout.h 951 2013-12-16 23:37:56Z Christian.Grefe@cern.ch $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +#if 0 +// Framework include files +#include "DDCond/ConditionValidator.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + + +/// Standard constructor +ConditionValidator::ConditionValidator() { +} + +/// Validate detector subtree and return conditions out of date +bool ConditionValidator::validate(DetElement subtree, std::vector<Condition>& tobe_updated) +{ + return true; +} +#endif diff --git a/DDCond/src/ConditionsHandler.cpp b/DDCond/src/ConditionsHandler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..98ec435218dacccd078467acbe8b3998159ebd39 --- /dev/null +++ b/DDCond/src/ConditionsHandler.cpp @@ -0,0 +1,115 @@ +// $Id: Geant4Setup.cpp 578 2013-05-17 22:33:09Z markus.frank $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== +// Framework include files +#include "DD4hep/LCDD.h" +#include "DD4hep/Printout.h" +#include "DD4hep/DetectorTools.h" +#include "DDCond/ConditionsHandler.h" +#include "DDCond/ConditionsOperators.h" +#include "DD4hep/objects/DetectorInterna.h" +#include "DD4hep/objects/ConditionsInterna.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; +typedef ConditionsStack::Entry Entry; + +/// Default constructor +ConditionsHandler::ConditionsHandler(LCDD& lcdd) + : m_lcdd(lcdd), m_refCount(1) +{ +} + +/// Default destructor +ConditionsHandler::~ConditionsHandler() { + printout(INFO,"ConditionsHandler","+++ Destroy cache"); +} + +/// Add reference count +int ConditionsHandler::addRef() { + return ++m_refCount; +} + +/// Release object. If reference count goes to NULL, automatic deletion is triggered. +int ConditionsHandler::release() { + int value = --m_refCount; + if ( value == 0 ) { + delete this; + } + return value; +} + +/// Open a new transaction stack (Note: only one stack allowed!) +void ConditionsHandler::openTransaction() { + /// Check if transaction already present. If not, open, else issue an error + if ( !ConditionsStack::exists() ) { + ConditionsStack::create(); + return; + } + string msg = "Request to open a second conditions transaction stack -- not allowed!"; + string err = format("Conditions<conditions>",msg); + printout(FATAL,"ConditionsHandler",msg); + throw runtime_error(err); +} + +/// Close existing transaction stack and apply all conditions +void ConditionsHandler::closeTransaction() { + /// Check if transaction is open. If yes, close it and apply conditions stack. + /// If no transaction is active, ignore the staement, but issue a warning. + if ( ConditionsStack::exists() ) { + ConditionsStack& stack = ConditionsStack::get(); + printout(DEBUG,"ConditionsHandler","+++ Closing conditions transaction...."); + apply(stack); + stack.release(); + printout(INFO,"ConditionsHandler","Conditions were applied...."); + return; + } + printout(WARNING,"Conditions<conditions>", + "Request to close a non-existing conditons transaction."); +} + +/// Create and install a new instance tree +void ConditionsHandler::install(LCDD& lcdd) { + ConditionsHandler* cache = lcdd.extension<ConditionsHandler>(false); + if ( !cache ) { + lcdd.addExtension<ConditionsHandler>(new ConditionsHandler(lcdd)); + } +} + +/// Unregister and delete a tree instance +void ConditionsHandler::uninstall(LCDD& lcdd) { + if ( lcdd.extension<ConditionsHandler>(false) ) { + lcdd.removeExtension<ConditionsHandler>(true); + } +} + +void ConditionsHandler::triggerUpdate(DetElement det) { + printout(DEBUG,"ConditionsHandler","+++ Trigger conditions update for %s",det.path().c_str()); + det._data().update(DetElement::CONDITIONS_CHANGED,(void*)0x1); +} + +/// Apply a complete stack of ordered conditionss to the geometry structure +void ConditionsHandler::apply(ConditionsStack& stack) { + typedef set<DetElement> Updates; + Updates updates; + + printout(DEBUG,"ConditionsHandler","+++ Apply conditions ...."); + while(stack.size() > 0) { + Entry* data = stack.pop().release(); + DetElement det = data->detector; + /// Do something! + printout(DEBUG,"ConditionsHandler","+++ %s name:%s type:%s value:%s Validity:%s", + det.path().c_str(), data->name.c_str(), data->type.c_str(), + data->value.c_str(), data->validity.c_str()); + det.conditions().set(data); + updates.insert(det); + } + // Now trigger update callbacks for all detector elements with changed conditions: + for_each(updates.begin(), updates.end(), triggerUpdate); +} diff --git a/DDCond/src/ConditionsParser.cpp b/DDCond/src/ConditionsParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5cb4bcbbd32aa105b0977ae0f545fa4804508cc5 --- /dev/null +++ b/DDCond/src/ConditionsParser.cpp @@ -0,0 +1,185 @@ +// $Id: Geant4Setup.cpp 578 2013-05-17 22:33:09Z markus.frank $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +// Framework include files +#include "DD4hep/LCDD.h" +#include "XML/Conversions.h" +#include "XML/XMLElements.h" +#include "XML/DocumentHandler.h" +#include "DD4hep/DetectorTools.h" +#include "DD4hep/DetFactoryHelper.h" +#include "DD4hep/objects/ConditionsInterna.h" + +#include "DDCond/ConditionsTags.h" +#include "DDCond/ConditionsStack.h" +#include "DDCond/ConditionsHandler.h" +#include "DDCond/ConditionsTransaction.h" + +// C/C++ include files +#include <stdexcept> + +/* + * DD4hep namespace declaration + */ +namespace DD4hep { + + namespace { + /// Some utility class to specialize the converters: + class include; + class arbitrary; + class conditions; + } + /// Forward declarations for all specialized converters + template <> void Converter<include>::operator()(xml_h seq) const; + template <> void Converter<arbitrary>::operator()(xml_h seq) const; + template <> void Converter<conditions>::operator()(xml_h seq) const; +} + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; +typedef ConditionsStack::Entry Entry; + +/// Helper: Extract the validity from the xml element +string _getValidity(xml_h elt) { + if ( !elt.ptr() ) + return "Infinite"; + else if ( !elt.hasAttr(_U(validity)) ) + return _getValidity(elt.parent()); + return elt.attr<string>(_U(validity)); +} + +/// Helper: Extract the required detector element from the parsing information +DetElement _getDetector(void* param, xml_h e) { + DetElement detector = param ? *(DetElement*)param : DetElement(); + string subpath = e.hasAttr(_U(path)) ? e.attr<string>(_U(path)) : string(); + return subpath.empty() ? detector : DetectorTools::findDaughterElement(detector,subpath); +} + +/// Helper: Extract the string value from the xml element +auto_ptr<Entry> _getStackEntry(void* param, xml_h element) { + xml_comp_t e(element); + DetElement elt = _getDetector(param, element); + string name = e.hasAttr(_U(name)) ? e.nameStr() : e.tag(); + auto_ptr<Entry> result(new Entry(elt,name,e.tag(),_getValidity(element))); + return result; +} + +/** Convert arbitrary conditon objects containing standard tags + * + * Function entry expects as a parameter a valid DetElement handle + * pointing to the subdetector, which detector elements should be + * realigned. + * + * <temperature path="/world/TPC" name="AbientTemperatur" value="20.9*Celcius"/> + * <temperature path="TPC" name="AbientTemperatur" value="20.9*Celcius"/> + * <temperature name="AbientTemperatur" value="20.9*Celcius"/> + * + * <temperature name="AbientTemperatur" value="20.9*Kelvin"/> + * <pressure name="external_pressure" value="980*hPa"/> + * <include ref="..."/> + * + * The object tag name is passed as the conditons type to the system. + * The data payload may either be specified as an attribute to the + * element or as text (data payload as the inner XML of the element). + * + * These items have: + * - a name defining the condition within the detector element + * - a value interpreted as a double. In XML the value may be dressed with a unit + * which will be correctly treated by the expression evaluator + * - a path (optionally). attribute_values are ALWAYS treated within the context + * of the containing detector element. If pathes are relative, they are + * relative to the embedding element. If pathes are absolute, the embedding + * element is ignored. + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ +template <> void Converter<arbitrary>::operator()(xml_h e) const { + xml_comp_t elt(e); + string tag = elt.tag(); + if ( tag == "open_transaction" ) + return; + else if ( tag == "close_transaction" ) + return; + else if ( tag == "include" ) + Converter<include>(lcdd,param)(e); + else if ( tag == "conditions" ) + Converter<conditions>(lcdd,param)(e); + else if ( tag == "detelement" ) + Converter<conditions>(lcdd,param)(e); + else if ( tag == "subdetectors" ) + xml_coll_t(e,_U(star)).for_each(Converter<conditions>(lcdd,param)); + else if ( tag == "detelements" ) + xml_coll_t(e,_U(star)).for_each(Converter<conditions>(lcdd,param)); + else { + auto_ptr<Entry> val(_getStackEntry(param,e)); + val->value = elt.hasAttr(_U(value)) ? elt.valueStr() : e.text(); + ConditionsStack::get().insert(val); + } +} + +/** Convert include objects + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ +template <> void Converter<include>::operator()(xml_h element) const { + XML::DocumentHolder doc(XML::DocumentHandler().load(element, element.attr_value(_U(ref)))); + xml_coll_t(doc.root(),_U(star)).for_each(Converter<arbitrary>(lcdd,param)); +} + +/** Convert objects containing standard conditions tags + * + * Function entry expects as a parameter a valid DetElement handle + * pointing to the subdetector, which detector elements should be + * realigned. A absolute or relative DetElement path may be supplied by + * the element as an attribute: + * + * <conditions path="/world/TPC/TPC_SideA/TPC_SideA_sector02"> + * ... + * </conditions> + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ +template <> void Converter<conditions>::operator()(xml_h e) const { + DetElement elt = _getDetector(param,e); + xml_coll_t(e,_U(star)).for_each(Converter<arbitrary>(lcdd,&elt)); +} + +/** Basic entry point to read conditions files + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ +static long setup_Conditions(lcdd_t& lcdd, const xml_h& e) { + ConditionsHandler::install(lcdd); + ConditionsTransaction tr(lcdd, e); + DetElement top = lcdd.world(); + (DD4hep::Converter<DD4hep::conditions>(lcdd,&top))(e); + return 1; +} +DECLARE_XML_DOC_READER(conditions,setup_Conditions) + +/** Basic entry point to install the conditions handler in a LCDD instance + * + * @author M.Frank + * @version 1.0 + * @date 01/04/2014 + */ +static long install_Conditions(lcdd_t& lcdd, int, char**) { + ConditionsHandler::install(lcdd); + return 1; +} +DECLARE_APPLY(DD4hepConditionsInstall,install_Conditions) diff --git a/DDCond/src/ConditionsStack.cpp b/DDCond/src/ConditionsStack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bf51e4cf8b750507fcfae2f34a6820625a53f858 --- /dev/null +++ b/DDCond/src/ConditionsStack.cpp @@ -0,0 +1,110 @@ +// $Id: XMLStack.h 889 2013-11-14 15:55:39Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +// Framework include files +#include "DD4hep/Printout.h" +#include "DD4hep/InstanceCount.h" +#include "DDCond/ConditionsStack.h" +#include "DD4hep/objects/ConditionsInterna.h" + +using namespace std; +using namespace DD4hep; +using namespace DD4hep::Geometry; + +static auto_ptr<ConditionsStack>& _stack() { + static auto_ptr<ConditionsStack> s; + return s; +} +static auto_ptr<ConditionsStack>& _stack(ConditionsStack* obj) { + auto_ptr<ConditionsStack>& s = _stack(); + s = auto_ptr<ConditionsStack>(obj); + return s; +} + +/// Standard constructor +ConditionsStack::ConditionsStack() { + InstanceCount::increment(this); +} + +/// Standard destructor +ConditionsStack::~ConditionsStack() { + destroyObjects(m_stack)(); + InstanceCount::decrement(this); +} + +/// Static client accessor +ConditionsStack& ConditionsStack::get() { + if ( _stack().get() ) return *_stack(); + throw runtime_error("ConditionsStack> Stack not allocated -- may not be retrieved!"); +} + +/// Create an conditions stack instance. The creation of a second instance will be refused. +void ConditionsStack::create() { + if ( _stack().get() ) { + throw runtime_error("ConditionsStack> Stack already allocated. Multiple copies are not allowed!"); + } + _stack(new ConditionsStack()); +} + +/// Check existence of conditions stack +bool ConditionsStack::exists() { + return _stack().get() != 0; +} + +/// Clear data content and remove the slignment stack +void ConditionsStack::release() { + if ( _stack().get() ) { + _stack(0); + return; + } + throw runtime_error("ConditionsStack> Attempt to delete non existing stack."); +} + +/// Retrieve an conditions entry of the current stack +auto_ptr<ConditionsStack::Entry> ConditionsStack::pop() { + Stack::iterator i = m_stack.begin(); + if ( i != m_stack.end() ) { + Entry* e = (*i).second; + m_stack.erase(i); + return auto_ptr<Entry>(e); + } + throw runtime_error("ConditionsStack> pop: Conditions stack is empty. Check size first!"); +} + +/// Get all pathes to be aligned +vector<const ConditionsStack::Entry*> ConditionsStack::entries() const { + vector<const Entry*> result; + result.reserve(m_stack.size()); + for(Stack::const_iterator i=m_stack.begin(); i != m_stack.end(); ++i) + result.push_back((*i).second); + return result; +} + +/// Push new entry into the stack +void ConditionsStack::insert(auto_ptr<Entry>& data) { + if ( data.get() && !data->name.empty() ) { + DetElement det = data->detector; + // Need to make some checks BEFORE insertion + if ( !det.isValid() ) { + throw runtime_error("ConditionsStack> Invalid conditions data [No such detector]"); + } + string path = det.path()+'!'+data->name; + Stack::const_iterator i = m_stack.find(path); + printout(DEBUG,"ConditionsStack","+++ %s name:%s type:%s value:%s Validity:%s", + det.path().c_str(), data->name.c_str(), data->type.c_str(), + data->value.c_str(), data->validity.c_str()); + if ( i == m_stack.end() ) { + m_stack.insert(make_pair(path,data.release())); + return; + } + throw runtime_error("ConditionsStack> The data with path "+path+ + " cannot be set twice in one transaction. [Intended inhibit]"); + } + throw runtime_error("ConditionsStack> Attempt to apply an invalid conditions data."); +} diff --git a/DDCond/src/ConditionsTags.cpp b/DDCond/src/ConditionsTags.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7ddea4ad3676a5fb5dfc7884d64040e86e323b2 --- /dev/null +++ b/DDCond/src/ConditionsTags.cpp @@ -0,0 +1,17 @@ +// $Id: XMLTags.h 889 2013-11-14 15:55:39Z markus.frank@cern.ch $ +//==================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +// Framework include files +#include "XML/XMLTags.h" + +// Define unicode tags +#ifndef UNICODE +#define UNICODE(x) DECLARE_UNICODE_TAG(x) +#endif +#include "DDCond/ConditionsTags.h" diff --git a/DDCond/src/ConditionsTransaction.cpp b/DDCond/src/ConditionsTransaction.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aaf60d9ca2241e61723e0b42d5e625f49874e45b --- /dev/null +++ b/DDCond/src/ConditionsTransaction.cpp @@ -0,0 +1,36 @@ +// $Id: Geant4Setup.cpp 578 2013-05-17 22:33:09Z markus.frank $ +//==================================================================== +// AIDA Detector description implementation for LCD +//-------------------------------------------------------------------- +// +// Author : M.Frank +// +//==================================================================== + +// Framework include files +#include "DD4hep/LCDD.h" +#include "DDCond/ConditionsTags.h" +#include "DDCond/ConditionsHandler.h" +#include "DDCond/ConditionsTransaction.h" + +using namespace DD4hep; +using namespace DD4hep::Geometry; + +/// Default constructor +ConditionsTransaction::ConditionsTransaction(LCDD& l, const XML::Handle_t& e) : lcdd(l) { + flag = e.hasChild(_U(close_transaction)); + /// First check if a transaction is to be opened + m_handler = lcdd.extension<Geometry::ConditionsHandler>(); + m_handler->addRef(); + if ( e.hasChild(_U(open_transaction)) ) { + m_handler->openTransaction(); + } +} +/// Default destructor +ConditionsTransaction::~ConditionsTransaction() { + /// Last check if a transaction is to be closed + if ( flag ) { + lcdd.extension<Geometry::ConditionsHandler>()->closeTransaction(); + } + m_handler->release(); +}