This page is intended to summarize the practical steps needed to provide specific sub-detector description parameters to physics algorithms. Please refer to the Detector Description chapter in the Gaudi User Guide for an overview of the Detector Description framework.
Define your sub-detector specific detector element class (transient). You must inherit your class from DetectorElement from where you will get the generic functionality and add your data members (your parameters) and specific methods. The following example is extracted from the VeloDetector class
#ifndef VELODETECTORELEMENT_H #define VELODETECTORELEMENT_H 1 // Include files #include "DetDesc/DetectorElement.h" #include "DetDesc/IGeometryInfo.h" // CLHEP files #include "CLHEP/Geometry/Transform3D.h" #include "CLHEP/Units/SystemOfUnits.h" #include "CLHEP/Units/PhysicalConstants.h" // CLID needs to be allocated static const CLID CLID_VeloDetectorElement = 4021; /** @class VeloDetectorElement * Velo detector element. * This class specialises the DetectorElement class to contain * information which may be common to \f$R\f$ and \f$\phi\f$ * silicon detectors. */ class VeloDetectorElement : public DetectorElement { public: /// Detector types enum Type {R, Phi}; /// Detector orientation enum Orientation {Upstream, Downstream, Unknown}; /// Constructors VeloDetectorElement() : m_orientation(Unknown) { } VeloDetectorElement(Type type) : m_type(type), m_orientation(Unknown) { } /// Destructor virtual ~VeloDetectorElement() { } /// Return detector type (\f$R\f$ or \f$\phi\f$) virtual Type type() const { return m_type; } /// Set detector type virtual void setType(Type type) { m_type = type; } /// Query detector type: is it an \f$R\f$ detector? virtual bool isR() const { return m_type==R; } /// Query detector type: is it a \f$\phi\f$ detector? virtual bool isPhi() const {return m_type==Phi; } /// Return detector orientation (upstream or downstream) virtual Orientation orientation() const { if (m_orientation == Unknown) { HepRotation rot = this->geometry()->matrixInv().getRotation(); Hep3Vector axis; HepDouble angle; rot.getAngleAxis(angle, axis); if (axis.theta()<halfpi) { m_orientation = Upstream; } else { m_orientation = Downstream; } } return m_orientation; } /// Set detector orientation virtual void setOrientation(Orientation orientation) { m_orientation = orientation;} private: Type m_type; ///< Detector type (\f$R\f$ or \f$\phi\f$) mutable Orientation m_orientation;///< Detector orientation (upstream or downstream) }; #endif // VELODETECTORELEMENT_H |
The CLID number needs to be allocated for your class. This number is used to match the transient class to the XML representation (you will need to use this number in the XML file). Implement your sub-detector specific methods in the .cpp file. The implementation of these classes should not include any XML stuff.
The sub-detector element specific classes should be put in a sub-detector package under the Det hat. The name of the package should contain the sub-detector name. For example the Det/VeloDet .
The element <detelem/> is used to define a detector element and it allows to include a <specific/> section in where the sub-detector specific information will be placed. The specification of <specific/> is done with a DTD fragment in the header of the file as is shown in this example:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE DDDB SYSTEM "../../DTD/structure.dtd" [ <!-- Velo specific entities --> <!ENTITY VeloDetID "4021"> <!-- Velo specific tags --> <!ELEMENT Detector EMPTY> <!ATTLIST Detector type ( R | Phi ) #REQUIRED> ]> |
The XML for a instance of a sub-detector element uses the <specific/> to pass specific parameters. In the following example this is the type of Velo detector (r or phi). In addition, to the specific paramters, the end-use has to define a number of parameters which apply to all detector elements, in particular the geometry information. All the XML files for all sub-detectors of LHCb are stored in the CVS repository in the Det/XmlDDDB package.
<detelem classID="&VeloDetID;" name="Detector00"> <author>Bruce Hay</author> <version>0.1</version> <geometryinfo lvname ="/dd/Geometry/Velo/lvVeloDetector" support="/dd/Structure/LHCb/Velo" rpath ="0/0"/> <specific> <Detector type="Phi"/> </specific> </detelem> |
For each type of specific detector element we need to provide a specific XML converter (the usual pattern within the Gaudi framework). This user specific converter needs to be capable of creating a new instances of the specific detector elements and initialize them with the information stored in the XML files. The end-user accessing the detector information do not need bother about the XML converters. Only the sub-detector specialists need to provide them.
We use the DOM interface of the XML parser to access the information in the XML file starting from version v8 of Gaudi. The user converter needs to inherit of templated class XmlUserDetElemCnv.
// Include files #include "DetDesc/XmlUserDetElemCnv.h" #include "DeMuonStation.h" /** @class
XmlMuonStationCnv class XmlVeloDetectorCnv : public
XmlUserDetElemCnv<VeloDetectorElement> { /// Default
destructor protected: /** This fills
the current object for specific child. ///
Instantiation of a static factory used by clients to create instances /// Constructor /// Fill an object with a new
specific child element // gets
the element's name std::string type =
attributes.getValue("type"); |