Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:16

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_FIELDS_H
0014 #define DD4HEP_FIELDS_H
0015 
0016 // Framework include files
0017 #include <DD4hep/NamedObject.h>
0018 #include <DD4hep/Objects.h>
0019 
0020 // C/C++ include files
0021 #include <vector>
0022 #include <map>
0023 
0024 /// Namespace for the AIDA detector description toolkit
0025 namespace dd4hep {
0026 
0027   // Forward declarations
0028   typedef Position Direction;
0029 
0030   /// Base class describing any field with 3D cartesian vectors for the field strength.
0031   /** Abstract base class describing any field (electric or magnetic) with 3D cartesian vectors 
0032    *  for the field strength and positions.
0033    *  Implementation classes need to overwrite void fieldComponents(const double* pos, double* field).
0034    *  The actual behaviour is solely implemented in the underlying object class.
0035    *
0036    *  \author  M.Frank
0037    *  \version 1.0
0038    *  \ingroup DD4HEP_CORE
0039    */
0040   class CartesianField: public Handle<NamedObject> {
0041   public:
0042     enum FieldType {
0043       UNKNOWN = 0, ELECTRIC = 0x1, MAGNETIC = 0x2, OVERLAY  = 0x4,
0044     };
0045     typedef std::map<std::string, std::map<std::string, std::string> > Properties;
0046 
0047     /// Internal data class shared by all handles of a given type
0048     /**
0049      *  \author  M.Frank
0050      *  \version 1.0
0051      *  \ingroup DD4HEP_CORE
0052      */
0053     class TypedObject : public NamedObject {
0054     public:
0055       /// Field type
0056       int   field_type { UNKNOWN };
0057       /// Default constructor
0058       using NamedObject::NamedObject;
0059     };
0060 
0061     /// Internal data class shared by all handles of a given type
0062     /**
0063      *  \author  M.Frank
0064      *  \version 1.0
0065      *  \ingroup DD4HEP_CORE
0066      */
0067     class Object: public TypedObject {
0068     public:
0069       /// Utility definition for concrete implementations
0070       typedef std::vector<double> Coefficents;
0071       /// Field extensions
0072       Properties properties;
0073       /// Default constructor
0074       Object();
0075       /// Default destructor
0076       virtual ~Object();
0077 
0078       /** Overwrite to compute the field components at a given location -
0079        *  NB: The field components have to be added to the provided
0080        *  field vector in order to allow for superposition of the fields.
0081        */
0082       virtual void fieldComponents(const double* pos, double* field) = 0;
0083     };
0084 
0085     /// Default constructor
0086     CartesianField() = default;
0087 
0088     /// Constructor to be used when reading the already parsed DOM tree
0089     CartesianField(const CartesianField& e) = default;
0090 
0091     /// Constructor to be used when reading the already parsed DOM tree
0092     template <typename Q> CartesianField(const Handle<Q>& e) : Ref_t(e) {
0093     }
0094 
0095     /// Assignment operator
0096     CartesianField& operator=(const CartesianField& f) = default;
0097 
0098     /// Access the field type
0099     int fieldType() const {
0100       return data<Object>()->field_type;
0101     }
0102 
0103     /// Access the field type (string)
0104     const char* type() const;
0105 
0106     /// Does the field change the energy of charged particles?
0107     bool changesEnergy() const;
0108 
0109     /// Returns the 3 field components (x, y, z).
0110     void value(const Position& pos, Direction& field) const;
0111 
0112     /// Returns the 3 field components (x, y, z).
0113     void value(const Position& pos, double* val) const;
0114 
0115     /// Returns the 3 field components (x, y, z).
0116     void value(const double* pos, double* val) const;
0117 
0118     /// Access to properties container
0119     Properties& properties() const;
0120   };
0121 
0122   /// Class describing a field overlay with several sources
0123   /**
0124    *  Generic structure describing any field type (electric or magnetic)
0125    *  with field components in Cartesian coordinates.
0126    *
0127    *  The actual behaviour is solely implemented in the underlying object
0128    *  classes. The overlay field is the sum of several magnetic of electric
0129    *  field components.
0130    *
0131    *  The resulting field vectors are computed by the vector addition
0132    *  of the individual components.
0133    *
0134    *  \author  M.Frank
0135    *  \version 1.0
0136    *  \ingroup DD4HEP_CORE
0137    */
0138   class OverlayedField: public Handle<NamedObject> {
0139   public:
0140     enum FieldType {
0141       ELECTRIC = CartesianField::ELECTRIC,
0142       MAGNETIC = CartesianField::MAGNETIC,
0143       OVERLAY  = CartesianField::OVERLAY,
0144     };
0145     typedef std::map<std::string, std::string> PropertyValues;
0146     typedef std::map<std::string, PropertyValues> Properties;
0147 
0148     /// Internal data class shared by all handles
0149     /**
0150      *  \author  M.Frank
0151      *  \version 1.0
0152      *  \ingroup DD4HEP_CORE
0153      */
0154     class Object: public CartesianField::TypedObject {
0155     public:
0156       CartesianField electric;
0157       CartesianField magnetic;
0158       std::vector<CartesianField> electric_components;
0159       std::vector<CartesianField> magnetic_components;
0160       /// Field extensions
0161       Properties properties;
0162 
0163     public:
0164       /// Default constructor
0165       Object();
0166       /// Default destructor
0167       virtual ~Object();
0168     };
0169 
0170     /// Default constructor
0171     OverlayedField() = default;
0172 
0173     /// Constructor to be used when reading the already parsed DOM tree
0174     template <typename Q>  OverlayedField(const Handle<Q>& e) : Ref_t(e) {      }
0175 
0176     /// Object constructor
0177     OverlayedField(const std::string& name);
0178 
0179     /// Access the field type
0180     int fieldType() const {
0181       return data<Object>()->field_type;
0182     }
0183 
0184     /// Does the field change the energy of charged particles?
0185     bool changesEnergy() const;
0186 
0187     /// Add a new field component
0188     void add(CartesianField field);
0189 
0190     /// Returns the 3 electric field components (x, y, z) if many components are present
0191     void combinedElectric(const Position& pos, double* field) const;
0192 
0193     /// Returns the 3 electric field components (x, y, z) if many components are present
0194     Direction combinedElectric(const Position& pos) const {
0195       double field[3] = { 0e0, 0e0, 0e0 };
0196       combinedElectric(pos, field);
0197       return {field[0], field[1], field[2]};
0198     }
0199 
0200     /// Returns the 3 electric field components (x, y, z) if many components are present
0201     void combinedElectric(const double* pos, double* field) const   {
0202       combinedElectric(Position(pos[0], pos[1], pos[2]), field);
0203     }
0204 
0205     /// Returns the 3 magnetic field components (x, y, z) if many components are present
0206     void combinedMagnetic(const Position& pos, double* field) const;
0207 
0208     /// Returns the 3 magnetic field components (x, y, z) at a given position
0209     Direction combinedMagnetic(const Position& pos) const {
0210       double field[3] = { 0e0, 0e0, 0e0 };
0211       combinedMagnetic({pos.X(), pos.Y(), pos.Z()}, field);
0212       return { field[0], field[1], field[2] };
0213     }
0214 
0215     /// Returns the 3 magnetic field components (x, y, z) if many components are present
0216     void combinedMagnetic(const double* pos, double* field) const   {
0217       combinedMagnetic(Position(pos[0], pos[1], pos[2]), field);
0218     }
0219 
0220     /// Returns the 3 electric field components (x, y, z).
0221     void electricField(const Position& pos, double* field) const;
0222 
0223     /// Returns the 3 electric field components (x, y, z) at a given position
0224     Direction electricField(const Position& pos) const {
0225       double field[3] = { 0e0, 0e0, 0e0 };
0226       electricField(pos, field);
0227       return { field[0], field[1], field[2] };
0228     }
0229 
0230     /// Returns the 3 electric field components (x, y, z).
0231     void electricField(const Position& pos, Direction& field) const {
0232       double fld[3] = { 0e0, 0e0, 0e0 };
0233       electricField(Position(pos.X(), pos.Y(), pos.Z()), fld);
0234       field = { fld[0], fld[1], fld[2] };
0235     }
0236 
0237     /// Returns the 3 electric field components (x, y, z).
0238     void electricField(const double* pos, double* field) const {
0239       field[0] = field[1] = field[2] = 0.0;
0240       CartesianField f = data<Object>()->electric;
0241       f.isValid() ? f.value(pos, field) : combinedElectric(pos, field);
0242     }
0243 
0244     /// Returns the 3  magnetic field components (x, y, z).
0245     void magneticField(const Position& pos, double* field) const;
0246 
0247     /// Returns the 3  magnetic field components (x, y, z).
0248     void magneticField(const double* pos, double* field) const   {
0249       magneticField(Position(pos[0], pos[1], pos[2]), field);
0250     }
0251 
0252     /// Returns the 3 magnetic field components (x, y, z).
0253     void magneticField(const double* pos, Direction& field) const {
0254       double fld[3] = { 0e0, 0e0, 0e0 };
0255       magneticField(Position(pos[0], pos[1], pos[2]), fld);
0256       field = { fld[0], fld[1], fld[2] };
0257     }
0258 
0259     /// Returns the 3 electric field components (x, y, z) at a given position
0260     Direction magneticField(const Position& pos) const {
0261       double field[3] = { 0e0, 0e0, 0e0 };
0262       magneticField(pos, field);
0263       return { field[0], field[1], field[2] };
0264     }
0265 
0266     /// Returns the 3 electric (val[0]-val[2]) and magnetic field components (val[3]-val[5]).
0267     void electromagneticField(const Position& pos, double* field) const;
0268 
0269     /// Returns the 3 electric (val[0]-val[2]) and magnetic field components (val[3]-val[5]).
0270     void electromagneticField(const double* pos, double* val) const   {
0271       electromagneticField(Position(pos[0], pos[1], pos[2]), val);
0272     }
0273 
0274     /// Access to properties container
0275     Properties& properties() const;
0276   };
0277 }         /* End namespace dd4hep             */
0278 #endif // DD4HEP_FIELDS_H