Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:36:56

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 #ifndef DD4HEP_VOLUMES_H
0014 #define DD4HEP_VOLUMES_H
0015 
0016 // Framework include files
0017 #include <DD4hep/Handle.h>
0018 #include <DD4hep/Shapes.h>
0019 #include <DD4hep/Objects.h>
0020 #include <DD4hep/BitField64.h>
0021 
0022 // C/C++ include files
0023 #include <map>
0024 #include <memory>
0025 
0026 // ROOT include file (includes TGeoVolume + TGeoShape)
0027 #include <TGeoNode.h>
0028 #include <TGeoPatternFinder.h>
0029 #include <TGeoExtension.h>
0030 
0031 /// Namespace for the AIDA detector description toolkit
0032 namespace dd4hep {
0033 
0034   class  Detector;
0035   class  Region;
0036   class  LimitSet;
0037   class  Material;
0038   class  VisAttr;
0039   class  DetElement;
0040   class  SensitiveDetector;
0041 
0042   // Forward declarations
0043   class  Volume;
0044   class  PlacedVolume;
0045 
0046   /// Scan geometry and create reflected volumes
0047   /**
0048    *   Build reflections the ROOT way. 
0049    *   To be called once the geometry is closed.
0050    *   This entity can only be invoked once.
0051    *
0052    *   For any further documentation please see the following ROOT documentation:
0053    *   \see http://root.cern.ch/root/html/TGeoManager.html
0054    *
0055    *   \author  M.Frank
0056    *   \version 1.0
0057    *   \ingroup DD4HEP_CORE
0058    */
0059   class  ReflectionBuilder   {
0060     Detector& detector;
0061   public:
0062     /// Initializing constructor
0063     ReflectionBuilder(Detector& desc) : detector(desc) {}
0064     /// Default descructor
0065     ~ReflectionBuilder() = default;
0066     /// Perform scan
0067     void execute()  const;
0068   };
0069     
0070   /// Implementation class extending the ROOT placed volume
0071   /**
0072    *   For any further documentation please see the following ROOT documentation:
0073    *   \see http://root.cern.ch/root/html/TGeoExtension.html
0074    *
0075    *   \author  M.Frank
0076    *   \version 1.0
0077    *   \ingroup DD4HEP_CORE
0078    */
0079   class PlacedVolumeExtension : public TGeoExtension  {
0080   public:
0081     typedef std::pair<std::string, int> VolID;
0082     /// Volume ID container
0083     /**
0084      *   \author  M.Frank
0085      *   \version 1.0
0086      *   \ingroup DD4HEP_CORE
0087      */
0088     class VolIDs: public std::vector<VolID> {
0089     public:
0090       typedef std::vector<VolID> Base;
0091       /// Default constructor
0092       VolIDs() = default;
0093       /// Move constructor
0094       VolIDs(VolIDs&& copy) = default;
0095       /// Copy constructor
0096       VolIDs(const VolIDs& copy) = default;
0097       /// Move assignment
0098       VolIDs& operator=(VolIDs&& copy)  = default;
0099       /// Assignment operator
0100       VolIDs& operator=(const VolIDs& c)  = default;
0101       /// Find entry
0102       std::vector<VolID>::const_iterator find(const std::string& name) const;
0103       /// Insert new entry
0104       std::pair<std::vector<VolID>::iterator, bool> insert(const std::string& name, int value);
0105       /// Insert bunch of entries
0106       template< class InputIt>
0107       iterator insert(InputIt first, InputIt last)
0108       {  return this->Base::insert(this->Base::end(), first, last);    }
0109 #if !defined __GNUCC__ || (defined __GNUCC__ && __GNUC__ > 5)
0110       /// Insert bunch of entries
0111       template< class InputIt>
0112       iterator insert(std::vector<VolID>::const_iterator pos, InputIt first, InputIt last)
0113       {  return this->Base::insert(pos, first, last);    }
0114 #endif
0115       /// String representation for debugging
0116       std::string str()  const;
0117     };
0118     class Parameterisation;
0119 
0120     /// Magic word to detect memory corruptions
0121     unsigned long magic { 0 };
0122     /// Reference count on object (used to implement Grab/Release)
0123     long   refCount     { 0 };
0124     /// Reference to the parameterised transformation
0125     Parameterisation* params   { nullptr };
0126     /// ID container
0127     VolIDs volIDs;
0128 
0129   public:
0130     /// Default constructor
0131     PlacedVolumeExtension();
0132     /// Default move
0133     PlacedVolumeExtension(PlacedVolumeExtension&& copy);
0134     /// Copy constructor
0135     PlacedVolumeExtension(const PlacedVolumeExtension& c);
0136     /// Default destructor
0137     virtual ~PlacedVolumeExtension();
0138     /// Move assignment
0139     PlacedVolumeExtension& operator=(PlacedVolumeExtension&& copy)  {
0140       magic  = std::move(copy.magic);
0141       params = std::move(copy.params);
0142       volIDs = std::move(copy.volIDs);
0143       return *this;
0144     }
0145     /// Assignment operator
0146     PlacedVolumeExtension& operator=(const PlacedVolumeExtension& copy) {
0147       magic  = copy.magic;
0148       params = copy.params;
0149       volIDs = copy.volIDs;
0150       return *this;
0151     }
0152     /// TGeoExtension overload: Method called whenever requiring a pointer to the extension
0153     virtual TGeoExtension *Grab()  override;
0154     /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore
0155     virtual void Release() const  override;
0156     /// Enable ROOT persistency
0157     ClassDefOverride(PlacedVolumeExtension,200);
0158   };
0159   class PlacedVolumeFeatureExtension : public  PlacedVolumeExtension {
0160   public:
0161   public:
0162   };
0163 
0164   /// Handle class holding a placed volume (also called physical volume)
0165   /**
0166    *   For any further documentation please see the following ROOT documentation:
0167    *   \see http://root.cern.ch/root/html/TGeoNode.html
0168    *
0169    *   \author  M.Frank
0170    *   \version 1.0
0171    *   \ingroup DD4HEP_CORE
0172    */
0173   class PlacedVolume : public Handle<TGeoNode> {
0174   public:
0175     typedef PlacedVolumeExtension         Object;
0176     typedef PlacedVolumeExtension::VolIDs VolIDs;
0177 
0178     /// Abstract base for processing callbacks to PlacedVolume objects
0179     /** Helper to facilitate building plugins, which instrument
0180      *  placements and volumes e.g. during geometry scans.
0181      *
0182      *  \author  M.Frank
0183      *  \version 1.0
0184      *  \ingroup DD4HEP_CORE
0185      */
0186     class Processor {
0187     public:
0188       /// Default constructor
0189       Processor();
0190       /// Default destructor
0191       virtual ~Processor();
0192       /// Container callback for object processing
0193       virtual int processPlacement(PlacedVolume pv) = 0;
0194     };
0195 
0196     /// Default constructor
0197     PlacedVolume() = default;
0198     /// Move constructor
0199     PlacedVolume(PlacedVolume&& e) = default;
0200     /// Copy assignment
0201     PlacedVolume(const PlacedVolume& e) = default;
0202     /// Copy assignment from other handle type
0203     template <typename T> PlacedVolume(const Handle<T>& e) : Handle<TGeoNode>(e) {  }
0204     /// Constructor taking implementation object pointer
0205     PlacedVolume(const TGeoNode* e) : Handle<TGeoNode>(e) {  }
0206     /// Assignment operator (must match copy constructor)
0207     PlacedVolume& operator=(PlacedVolume&& v)  = default;
0208     /// Assignment operator (must match copy constructor)
0209     PlacedVolume& operator=(const PlacedVolume& v)  = default;
0210     /// Equality operator
0211     template <typename T> bool operator ==(const Handle<T>& e) const {
0212       return ptr() == e.ptr();
0213     }
0214     /// Non-Equality operator
0215     template <typename T> bool operator !=(const Handle<T>& e) const {
0216       return ptr() != e.ptr();
0217     }
0218 
0219     /// Check if placement is properly instrumented
0220     Object* data() const;
0221     /// Access the object type from the class information
0222     const char* type() const;
0223     /// Access the copy number of this placement within its mother
0224     int copyNumber() const;
0225     /// Volume material
0226     Material material() const;
0227     /// Logical volume of this placement
0228     Volume volume() const;
0229     /// Parent volume (envelope)
0230     Volume motherVol() const;
0231     /// Number of daughters placed in this volume
0232     std::size_t num_daughters()  const;
0233     /// Access the daughter by index
0234     PlacedVolume daughter(std::size_t which)  const;
0235     /// Access the full transformation matrix to the parent volume
0236     const TGeoMatrix& matrix()  const;
0237     /// Access the translation vector to the parent volume
0238     Position position()  const;
0239     /// Access to the volume IDs
0240     const PlacedVolumeExtension::VolIDs& volIDs() const;
0241     /// Add identifier
0242     PlacedVolume& addPhysVolID(const std::string& name, int value);
0243     /// String dump
0244     std::string toString() const;
0245   };
0246 
0247   // This needs full knowledge of the PlacedVolume class, at least for ROOT 6.28/04
0248   // so we place it here
0249   /// Optional parameters to implement special features such as parametrization
0250   /**
0251    *
0252    *   \author  M.Frank
0253    *   \version 1.0
0254    *   \ingroup DD4HEP_CORE
0255    */
0256   class PlacedVolumeExtension::Parameterisation {
0257   public:
0258     /** Feature: Geant4 parameterised volumes  */
0259     using Dimension = std::pair<Transform3D, size_t>;
0260     /// Reference to the starting point of the parameterisation
0261     Transform3D   start    {   };
0262     /// Reference to the parameterised transformation for dimension 1
0263     Dimension     trafo1D  { {}, 0UL };
0264     /// Reference to the parameterised transformation for dimension 2
0265     Dimension     trafo2D  { {}, 0UL };
0266     /// Reference to the parameterised transformation for dimension 3
0267     Dimension     trafo3D  { {}, 0UL };
0268     /// Number of entries for the parameterisation in dimension 2
0269     unsigned long flags    { 0 };
0270     /// Number of entries for the parameterisation in dimension 2
0271     unsigned long refCount { 0 };
0272     /// Reference to the placements of this volume
0273     std::vector<PlacedVolume> placements {  };
0274     /// Bitfield from sensitive detector to encode the volume ID on the fly
0275     const detail::BitFieldElement* field { nullptr };
0276 
0277   public:
0278     /// Default constructor
0279     Parameterisation() = default;
0280     /// Default move
0281     Parameterisation(Parameterisation&& copy) = default;
0282     /// Copy constructor
0283     Parameterisation(const Parameterisation& c) = default;
0284     /// Default destructor
0285     virtual ~Parameterisation() = default;
0286     /// Move assignment
0287     Parameterisation& operator=(Parameterisation&& copy) = default;
0288     /// Assignment operator
0289     Parameterisation& operator=(const Parameterisation& copy) = default;
0290     /// Increase ref count
0291     Parameterisation* addref();
0292     /// Decrease ref count
0293     void release();
0294     /// Enable ROOT persistency
0295     ClassDef(Parameterisation,200);
0296   };
0297 
0298 
0299   /// Implementation class extending the ROOT volume (TGeoVolume)
0300   /**
0301    *   Internal data structure optional to TGeo data.
0302    *
0303    *   For any further documentation please see the following ROOT documentation:
0304    *   \see http://root.cern.ch/root/html/TGeoExtension.html
0305    *
0306    *   \author  M.Frank
0307    *   \version 1.0
0308    *   \ingroup DD4HEP_CORE
0309    */
0310   class VolumeExtension : public TGeoExtension {
0311   public:
0312     /// Magic word to detect memory corruptions
0313     unsigned long       magic      = 0;
0314     /// Reference count on object (used to implement Grab/Release)
0315     long                refCount   = 0;
0316     ///
0317     int                 referenced = 0;
0318     /// Bit field to determine the usage. Bit 0...15 reserverd for system usage. 16...31 user space.
0319     int                 flags      = 0;
0320     /// Region reference
0321     Region              region;
0322     /// Limit sets used for simulation
0323     LimitSet            limits;
0324     /// Reference to visualization attributes
0325     VisAttr             vis;
0326     /// Reference to the sensitive detector
0327     Handle<NamedObject> sens_det;
0328     /// Reference to the reflected volume (or to the original volume for reflections)
0329     Handle<TGeoVolume>  reflected;
0330     /// Reference to properties
0331     TList* properties  { nullptr };
0332 
0333     /// Default destructor
0334     virtual ~VolumeExtension();
0335     /// Default constructor
0336     VolumeExtension();
0337     /// No move
0338     VolumeExtension(VolumeExtension&& copy) = delete;
0339     /// Copy constructor
0340     VolumeExtension(const VolumeExtension& copy);
0341     /// No move assignment
0342     VolumeExtension& operator=(VolumeExtension&& copy) = delete;
0343     /// Copy assignment
0344     VolumeExtension& operator=(const VolumeExtension& copy);
0345     /// Copy the object
0346     void copy(const VolumeExtension& c);
0347     /// TGeoExtension overload: Method called whenever requiring a pointer to the extension
0348     virtual TGeoExtension *Grab()  override;
0349     /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore
0350     virtual void Release() const  override;
0351     /// Enable ROOT persistency
0352     ClassDefOverride(VolumeExtension,200);
0353   };
0354 
0355   /// Handle class holding a placed volume (also called physical volume)
0356   /**
0357    *   Handle describing a Volume
0358    *
0359    *   One note about divisions:
0360    *   =========================
0361    *   Since dd4hep requires Volumes (aka TGeoVolume) and PlacedVolumes (aka TGeoNode)
0362    *   to be enhaced with the user extension mechanism shape divisions MUST be
0363    *   done using the division mechanism of the dd4hep shape or volume wrapper.
0364    *   Otherwise the enhancements are not added and you shall get exception
0365    *   when dd4hep is closing the geometry.
0366    *   The same argument holds when a division is made from a Volume.
0367    *   Unfortunately there is no reasonable way to intercept this call to the
0368    *   TGeo objects - except to sub-class each of them, which is not really 
0369    *   acceptable either.
0370    *
0371    *   For any further documentation please see the following ROOT documentation:
0372    *   \see http://root.cern.ch/root/html/TGeoVolume.html
0373    *
0374    *   \author  M.Frank
0375    *   \version 1.0
0376    *   \ingroup DD4HEP_CORE
0377    */
0378   class Volume: public Handle<TGeoVolume> {
0379   public:
0380     typedef VolumeExtension Object;
0381     /// Flag bit numbers for special volume treatments
0382     enum  {
0383       VETO_SIMU     = 1,
0384       VETO_RECO     = 2,
0385       VETO_DISPLAY  = 3,
0386       REFLECTED     = 10,
0387     };
0388     enum ReplicationAxis  {
0389       REPLICATED    = 1UL << 4,
0390       PARAMETERIZED = 1UL << 5,
0391       Undefined     = 1UL << 7,
0392       X_axis        = 1UL << 8,
0393       Y_axis        = 1UL << 9,
0394       Z_axis        = 1UL << 10,
0395       Rho_axis      = 1UL << 11,
0396       Phi_axis      = 1UL << 12
0397     };
0398   
0399   public:
0400     /// Default constructor
0401     Volume() = default;
0402     /// Move from handle
0403     Volume(Volume&& v) = default;
0404     /// Copy from handle
0405     Volume(const Volume& v) = default;
0406     /// Copy from handle
0407     Volume(const TGeoVolume* v) : Handle<TGeoVolume>(v) { }
0408     /// Copy from arbitrary Element
0409     template <typename T> Volume(const Handle<T>& v) : Handle<TGeoVolume>(v) {  }
0410 
0411     /// Constructor to be used when creating a new geometry tree.
0412     Volume(const std::string& name);
0413     /// Constructor to be used when creating a new geometry tree. Sets also title
0414     Volume(const std::string& name, const std::string& title);
0415 
0416     /// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes
0417     Volume(const std::string& name, const Solid& s, const Material& m);
0418 
0419     /// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes
0420     Volume(const std::string& name, const std::string& title, const Solid& s, const Material& m);
0421 
0422     /// Assignment operator (must match move constructor)
0423     Volume& operator=(Volume&& a)  = default;
0424     /// Assignment operator (must match copy constructor)
0425     Volume& operator=(const Volume& a)  = default;
0426     /// Equality operator
0427     template <typename T> bool operator ==(const Handle<T>& e) const {
0428       return ptr() == e.ptr();
0429     }
0430     /// Non-Equality operator
0431     template <typename T> bool operator !=(const Handle<T>& e) const {
0432       return ptr() != e.ptr();
0433     }
0434 
0435     /// Set flag to enable copy number checks when inserting new nodes
0436     /** By default checks are enabled. If you want to disable, call this function */
0437     static void enableCopyNumberCheck(bool value);
0438     
0439     /// Check if placement is properly instrumented
0440     Object* data() const;
0441 
0442     /// Access the object type from the class information
0443     const char* type() const;
0444 
0445     /// Create a reflected volume tree. The reflected volume has left-handed coordinates
0446     Volume reflect()  const;
0447 
0448     /// Create a reflected volume tree. The reflected volume has left-handed coordinates.
0449     /** Swap the sensitive detector - if valid - on all sensitive sub-volumes
0450      */
0451     Volume reflect(SensitiveDetector sd)  const;
0452     
0453     /// If we import volumes from external sources, we have to attach the extensions to the tree
0454     Volume& import();
0455 
0456     /// Divide volume into subsections (See the ROOT manuloa for details)
0457     Volume divide(const std::string& divname, int iaxis, int ndiv, double start, double step, int numed = 0, const char* option = "");
0458     /** Daughter placements with auto-generated copy number for the daughter volume  */
0459     /// Place daughter volume. The position and rotation are the identity
0460     PlacedVolume placeVolume(const Volume& volume) const;
0461     /// Place daughter volume according to a generic Transform3D
0462     PlacedVolume placeVolume(const Volume& volume, const Transform3D& tr) const;
0463     /// Place un-rotated daughter volume at the given position.
0464     PlacedVolume placeVolume(const Volume& volume, const Position& pos) const;
0465     /// Place rotated daughter volume. The position is automatically the identity position
0466     PlacedVolume placeVolume(const Volume& volume, const RotationZYX& rot) const;
0467     /// Place rotated daughter volume. The position is automatically the identity position
0468     PlacedVolume placeVolume(const Volume& volume, const Rotation3D& rot) const;
0469 
0470     /** Daughter placements with user supplied copy number for the daughter volume  */
0471     /// Place daughter volume. The position and rotation are the identity
0472     PlacedVolume placeVolume(const Volume& volume, int copy_no) const;
0473     /// Place daughter volume according to a generic Transform3D
0474     PlacedVolume placeVolume(const Volume& volume, int copy_no, const Transform3D& tr) const;
0475     /// Place un-rotated daughter volume at the given position.
0476     PlacedVolume placeVolume(const Volume& volume, int copy_no, const Position& pos) const;
0477     /// Place rotated daughter volume. The position is automatically the identity position
0478     PlacedVolume placeVolume(const Volume& volume, int copy_no, const RotationZYX& rot) const;
0479     /// Place rotated daughter volume. The position is automatically the identity position
0480     PlacedVolume placeVolume(const Volume& volume, int copy_no, const Rotation3D& rot) const;
0481     /// Place daughter volume with generic TGeo matrix
0482     PlacedVolume placeVolume(const Volume& volume, TGeoMatrix* tr) const;
0483     /// Place daughter volume with generic TGeo matrix
0484     PlacedVolume placeVolume(const Volume& volume, int copy_nr, TGeoMatrix* tr) const;
0485     /// 1D volume replication implementation
0486     /** Embedding parameterised daughter placements in a mother volume
0487      *  @param entity Daughter volume to be placed
0488      *  @param axis   Replication axis direction in the frame of the mother
0489      *  @param count  Number of entities to be placed
0490      *  @param inc    Transformation increment for each iteration
0491      *  @param start  start transormation for the first placement
0492      */
0493     PlacedVolume replicate(const Volume entity, ReplicationAxis axis, size_t count, double inc, double start=0e0);
0494     /// 1D Parameterised volume implementation
0495     /** Embedding parameterised daughter placements in a mother volume
0496      *  @param start  start transormation for the first placement
0497      *  @param entity Daughter volume to be placed
0498      *  @param count  Number of entities to be placed
0499      *  @param inc    Transformation increment for each iteration
0500      */
0501     PlacedVolume paramVolume1D(const Transform3D& start, Volume entity, size_t count, const Transform3D& inc);
0502     /// 1D Parameterised volume implementation
0503     /** Embedding parameterised daughter placements in a mother volume
0504      *  @param entity Daughter volume to be placed
0505      *  @param count  Number of entities to be placed
0506      *  @param inc    Transformation increment for each iteration
0507      */
0508     PlacedVolume paramVolume1D(Volume entity, size_t count, const Transform3D& trafo);
0509     /// 1D Parameterised volume implementation
0510     /** Embedding parameterised daughter placements in a mother volume
0511      *  @param entity Daughter volume to be placed
0512      *  @param count  Number of entities to be placed
0513      *  @param inc    Transformation increment for each iteration
0514      */
0515     PlacedVolume paramVolume1D(Volume entity, size_t count, const Position& inc);
0516     /// 1D Parameterised volume implementation
0517     /** Embedding parameterised daughter placements in a mother volume
0518      *  @param entity Daughter volume to be placed
0519      *  @param count  Number of entities to be placed
0520      *  @param inc    Transformation increment for each iteration
0521      */
0522     PlacedVolume paramVolume1D(Volume entity, size_t count, const RotationZYX& inc);
0523 
0524     /// 2D Parameterised volume implementation
0525     /** Embedding parameterised daughter placements in a mother volume
0526      *  @param entity   Daughter volume to be placed
0527      *  @param count_1  Number of entities to be placed in dimension 1
0528      *  @param inc_1    Transformation increment for each iteration in dimension 1
0529      *  @param count_2  Number of entities to be placed in dimension 2
0530      *  @param inc_2    Transformation increment for each iteration in dimension 2
0531      */
0532     PlacedVolume paramVolume2D(Volume entity, 
0533                    size_t count_1, const Transform3D& inc_1,
0534                    size_t count_2, const Transform3D& inc_2);
0535 
0536     /// Constructor to be used when creating a new parameterised volume object
0537     /** Embedding parameterised daughter placements in a mother volume
0538      *  @param start    start transormation for the first placement
0539      *  @param entity   Daughter volume to be placed
0540      *  @param count_1  Number of entities to be placed in dimension 1
0541      *  @param inc_1    Transformation increment for each iteration in dimension 1
0542      *  @param count_2  Number of entities to be placed in dimension 2
0543      *  @param inc_2    Transformation increment for each iteration in dimension 2
0544      */
0545     PlacedVolume paramVolume2D(const Transform3D& start,
0546                    Volume entity,
0547                    size_t count_1,
0548                    const Position& inc_1,
0549                    size_t count_2,
0550                    const Position& inc_2);
0551 
0552     /// Constructor to be used when creating a new parameterised volume object
0553     /** Embedding parameterised daughter placements in a mother volume
0554      *  @param start    start transormation for the first placement
0555      *  @param entity   Daughter volume to be placed
0556      *  @param count_1  Number of entities to be placed in dimension 1
0557      *  @param inc_1    Transformation increment for each iteration in dimension 1
0558      *  @param count_2  Number of entities to be placed in dimension 2
0559      *  @param inc_2    Transformation increment for each iteration in dimension 2
0560      */
0561     PlacedVolume paramVolume2D(Volume entity,
0562                    size_t count_1,
0563                    const Position& inc_1,
0564                    size_t count_2,
0565                    const Position& inc_2);
0566 
0567     /// 2D Parameterised volume implementation
0568     /** Embedding parameterised daughter placements in a mother volume
0569      *  @param start    start transormation for the first placement
0570      *  @param entity   Daughter volume to be placed
0571      *  @param count_1  Number of entities to be placed in dimension 1
0572      *  @param inc_1    Transformation increment for each iteration in dimension 1
0573      *  @param count_2  Number of entities to be placed in dimension 2
0574      *  @param inc_2    Transformation increment for each iteration in dimension 2
0575      */
0576     PlacedVolume paramVolume2D(const Transform3D& start, Volume entity, 
0577                    size_t count_1, const Transform3D& inc_1,
0578                    size_t count_2, const Transform3D& inc_2);
0579 
0580     /// 3D Parameterised volume implementation
0581     /** Embedding parameterised daughter placements in a mother volume
0582      *  @param entity   Daughter volume to be placed
0583      *  @param count_1  Number of entities to be placed in dimension 1
0584      *  @param inc_1    Transformation increment for each iteration in dimension 1
0585      *  @param count_2  Number of entities to be placed in dimension 2
0586      *  @param inc_2    Transformation increment for each iteration in dimension 2
0587      *  @param count_3  Number of entities to be placed in dimension 3
0588      *  @param inc_3    Transformation increment for each iteration in dimension 3
0589      */
0590     PlacedVolume paramVolume3D(Volume entity, 
0591                    size_t count_1, const Transform3D& inc_1,
0592                    size_t count_2, const Transform3D& inc_2,
0593                    size_t count_3, const Transform3D& inc_3);
0594 
0595     /// 3D Parameterised volume implementation
0596     /** Embedding parameterised daughter placements in a mother volume
0597      *  @param start    start transormation for the first placement
0598      *  @param entity   Daughter volume to be placed
0599      *  @param count_1  Number of entities to be placed in dimension 1
0600      *  @param inc_1    Transformation increment for each iteration in dimension 1
0601      *  @param count_2  Number of entities to be placed in dimension 2
0602      *  @param inc_2    Transformation increment for each iteration in dimension 2
0603      *  @param count_3  Number of entities to be placed in dimension 3
0604      *  @param inc_3    Transformation increment for each iteration in dimension 3
0605      */
0606     PlacedVolume paramVolume3D(const Transform3D& start, Volume entity, 
0607                    size_t count_1, const Transform3D& inc_1,
0608                    size_t count_2, const Transform3D& inc_2,
0609                    size_t count_3, const Transform3D& inc_3);
0610 
0611     /// 3D Parameterised volume implementation
0612     /** Embedding parameterised daughter placements in a mother volume
0613      *  @param entity   Daughter volume to be placed
0614      *  @param count_1  Number of entities to be placed in dimension 1
0615      *  @param inc_1    Transformation increment for each iteration in dimension 1
0616      *  @param count_2  Number of entities to be placed in dimension 2
0617      *  @param inc_2    Transformation increment for each iteration in dimension 2
0618      *  @param count_3  Number of entities to be placed in dimension 3
0619      *  @param inc_3    Transformation increment for each iteration in dimension 3
0620      */
0621     PlacedVolume paramVolume3D(Volume entity, 
0622                    size_t count_1, const Position& inc_1,
0623                    size_t count_2, const Position& inc_2,
0624                    size_t count_3, const Position& inc_3);
0625 
0626     /// 3D Parameterised volume implementation
0627     /** Embedding parameterised daughter placements in a mother volume
0628      *  @param start    start transormation for the first placement
0629      *  @param entity   Daughter volume to be placed
0630      *  @param count_1  Number of entities to be placed in dimension 1
0631      *  @param inc_1    Transformation increment for each iteration in dimension 1
0632      *  @param count_2  Number of entities to be placed in dimension 2
0633      *  @param inc_2    Transformation increment for each iteration in dimension 2
0634      *  @param count_3  Number of entities to be placed in dimension 3
0635      *  @param inc_3    Transformation increment for each iteration in dimension 3
0636      */
0637     PlacedVolume paramVolume3D(const Transform3D& start, Volume entity, 
0638                    size_t count_1, const Position& inc_1,
0639                    size_t count_2, const Position& inc_2,
0640                    size_t count_3, const Position& inc_3);
0641 
0642     /// Set user flags in bit-field
0643     void setFlagBit(unsigned int bit);
0644     /// Test the user flag bit
0645     bool testFlagBit(unsigned int bit)   const;
0646 
0647     /// Test if this volume was reflected
0648     bool isReflected()   const;
0649     
0650     /// Test if this volume is an assembly structure
0651     bool isAssembly()   const;
0652 
0653     /// Set the volume's option value
0654     const Volume& setOption(const std::string& opt) const;
0655     /// Access the volume's option value
0656     std::string option() const;
0657 
0658     /// Attach attributes to the volume
0659     const Volume& setAttributes(const Detector& description, const std::string& region, const std::string& limits,
0660                                 const std::string& vis) const;
0661 
0662     /// Set the regional attributes to the volume. Note: If the name string is empty, the action is ignored.
0663     const Volume& setRegion(const Detector& description, const std::string& name) const;
0664     /// Set the regional attributes to the volume
0665     const Volume& setRegion(const Region& obj) const;
0666     /// Access to the handle to the region structure
0667     Region region() const;
0668 
0669     /// Set the limits to the volume. Note: If the name string is empty, the action is ignored.
0670     const Volume& setLimitSet(const Detector& description, const std::string& name) const;
0671     /// Set the limits to the volume
0672     const Volume& setLimitSet(const LimitSet& obj) const;
0673     /// Access to the limit set
0674     LimitSet limitSet() const;
0675 
0676     /// Set Visualization attributes to the volume
0677     const Volume& setVisAttributes(const VisAttr& obj) const;
0678     /// Set Visualization attributes to the volume. Note: If the name string is empty, the action is ignored.
0679     const Volume& setVisAttributes(const Detector& description, const std::string& name) const;
0680     /// Access the visualisation attributes
0681     VisAttr visAttributes() const;
0682 
0683     /// Assign the sensitive detector structure
0684     const Volume& setSensitiveDetector(const SensitiveDetector& obj) const;
0685     /// Access to the handle to the sensitive detector
0686     Handle<NamedObject> sensitiveDetector() const;
0687     /// Accessor if volume is sensitive (ie. is attached to a sensitive detector)
0688     bool isSensitive() const;
0689 
0690     /// Set the volume's solid shape
0691     const Volume& setSolid(const Solid& s) const;
0692     /// Access to Solid (Shape)
0693     Solid solid() const;
0694     /// Access the bounding box of the volume (if available)
0695     Box boundingBox() const;
0696 
0697     /// Set the volume's material
0698     const Volume& setMaterial(const Material& m) const;
0699     /// Access to the Volume material
0700     Material material() const;
0701 
0702     /// Check for existence of properties
0703     bool hasProperties()  const;
0704 
0705     /// Add Volume property (name-value pair)
0706     void addProperty(const std::string& nam, const std::string& val)  const;
0707 
0708     /// Access property value. Returns default_value if the property is not present
0709     std::string getProperty(const std::string& nam, const std::string& default_val="")  const;
0710 
0711     /// Auto conversion to underlying ROOT object
0712     operator TGeoVolume*() const {
0713       return m_element;
0714     }
0715   };
0716 
0717   /// Implementation class extending the ROOT mulit-volumes (TGeoVolumeMulti)
0718   /**
0719    *  Handle describing a multi volume.
0720    *
0721    *   For any further documentation please see the following ROOT documentation:
0722    *   \see http://root.cern.ch/root/html/TGeoVolumeMulti.html
0723    *
0724    *   \author  M.Frank
0725    *   \version 1.0
0726    *   \ingroup DD4HEP_CORE
0727    */
0728   class VolumeMulti : public Volume   {
0729     /// Import volume from pointer as a result of Solid->Divide()
0730     void verifyVolumeMulti();
0731 
0732   public:
0733     /// Default constructor
0734     VolumeMulti() = default;
0735     /// Copy from handle
0736     VolumeMulti(const VolumeMulti& v) = default;
0737     /// Copy from pointer as a result of Solid->Divide()
0738     VolumeMulti(TGeoVolume* v) : Volume(v)  {
0739       verifyVolumeMulti();
0740     }
0741     /// Copy from arbitrary Element
0742     template <typename T> VolumeMulti(const Handle<T>& v) : Volume(v) {
0743       verifyVolumeMulti();
0744     }
0745     /// Constructor to be used when creating a new multi-volume object
0746     VolumeMulti(const std::string& name, Material material);
0747     /// Assignment operator (must match copy constructor)
0748     VolumeMulti& operator=(const VolumeMulti& a) = default;
0749   };
0750 
0751   /// Implementation class extending the ROOT assembly volumes (TGeoVolumeAssembly)
0752   /**
0753    *  Handle describing a volume assembly.
0754    *
0755    *   For any further documentation please see the following ROOT documentation:
0756    *   \see http://root.cern.ch/root/html/TGeoVolumeAssembly.html
0757    *
0758    *   \author  M.Frank
0759    *   \version 1.0
0760    *   \ingroup DD4HEP_CORE
0761    */
0762   class Assembly: public Volume {
0763   public:
0764     /// Default constructor
0765     Assembly() = default;
0766     /// Copy from handle
0767     Assembly(const Assembly& v) = default;
0768     /// Copy from arbitrary Element
0769     template <typename T> Assembly(const Handle<T>& v) : Volume(v) {  }
0770     /// Constructor to be used when creating a new assembly object
0771     Assembly(const std::string& name);
0772     /// Assignment operator (must match copy constructor)
0773     Assembly& operator=(const Assembly& a) = default;
0774   };
0775 
0776   /// Output mesh vertices to string
0777   std::string toStringMesh(PlacedVolume solid, int precision=2);
0778 }         /* End namespace dd4hep          */
0779 #endif // DD4HEP_VOLUMES_H