Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:13:54

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 
0014 #include <DD4hep/Fields.h>
0015 #include <DD4hep/Printout.h>
0016 #include <DD4hep/InstanceCount.h>
0017 #include <DD4hep/detail/Handle.inl>
0018 
0019 using namespace dd4hep;
0020 
0021 typedef CartesianField::Object CartesianFieldObject;
0022 DD4HEP_INSTANTIATE_HANDLE(CartesianFieldObject);
0023 
0024 typedef OverlayedField::Object OverlayedFieldObject;
0025 DD4HEP_INSTANTIATE_HANDLE(OverlayedFieldObject);
0026 
0027 namespace {
0028   void calculate_combined_field(std::vector<CartesianField>& v, const Position& pos, double* field) {
0029     for (const auto& i : v ) i.value(pos, field);
0030   }
0031 }
0032 
0033 /// Default constructor
0034 CartesianField::Object::Object() : TypedObject()  {
0035   // The field_type MUST be overriden by the concrete sublass!
0036   field_type = UNKNOWN;
0037   InstanceCount::increment(this);
0038 }
0039 
0040 /// Default destructor
0041 CartesianField::Object::~Object() {
0042   InstanceCount::decrement(this);
0043 }
0044 
0045 /// Access the field type (string)
0046 const char* CartesianField::type() const {
0047   return m_element->GetTitle();
0048 }
0049 
0050 /// Does the field change the energy of charged particles?
0051 bool CartesianField::changesEnergy() const {
0052   return ELECTRIC == (fieldType() & ELECTRIC);
0053 }
0054 
0055 /// Access to properties container
0056 CartesianField::Properties& CartesianField::properties() const {
0057   return data<Object>()->properties;
0058 }
0059 
0060 /// Returns the 3 field components (x, y, z).
0061 void CartesianField::value(const Position& pos, Direction& field) const  {
0062   double fld[3] = {0e0, 0e0, 0e0};
0063   double position[3] = {pos.X(), pos.Y(), pos.Z()};
0064   data<Object>()->fieldComponents(position, fld);
0065   field = Direction(fld[0], fld[1], fld[2]);
0066 }
0067 
0068 /// Returns the 3 field components (x, y, z).
0069 void CartesianField::value(const Position& pos, double* field) const   {
0070   double position[3] = {pos.X(), pos.Y(), pos.Z()};
0071   data<Object>()->fieldComponents(position, field);
0072 }
0073 
0074 /// Returns the 3 field components (x, y, z).
0075 void CartesianField::value(const double* pos, double* field) const {
0076   data<Object>()->fieldComponents(pos, field);
0077 }
0078 
0079 /// Default constructor
0080 OverlayedField::Object::Object() : TypedObject(), electric(), magnetic()
0081 {
0082   field_type = CartesianField::OVERLAY;
0083   InstanceCount::increment(this);
0084 }
0085 
0086 /// Default destructor
0087 OverlayedField::Object::~Object() {
0088   InstanceCount::decrement(this);
0089 }
0090 
0091 /// Object constructor
0092 OverlayedField::OverlayedField(const std::string& nam) : Ref_t() {
0093   auto* obj = new Object();
0094   assign(obj, nam, "overlay_field");
0095   obj->field_type = CartesianField::OVERLAY;
0096 }
0097 
0098 /// Access to properties container
0099 OverlayedField::Properties& OverlayedField::properties() const {
0100   return data<Object>()->properties;
0101 }
0102 
0103 /// Does the field change the energy of charged particles?
0104 bool OverlayedField::changesEnergy() const {
0105   int field = data<Object>()->field_type;
0106   return CartesianField::ELECTRIC == (field & CartesianField::ELECTRIC);
0107 }
0108 
0109 /// Add a new field component
0110 void OverlayedField::add(CartesianField field) {
0111   if (field.isValid()) {
0112     Object* o = data<Object>();
0113     if ( o ) {
0114       int  typ   = field.fieldType();
0115       bool isEle = field.ELECTRIC == (typ & field.ELECTRIC);
0116       bool isMag = field.MAGNETIC == (typ & field.MAGNETIC);
0117       if (isEle) {
0118         std::vector < CartesianField > &v = o->electric_components;
0119         v.emplace_back(field);
0120         o->field_type |= field.ELECTRIC;
0121         o->electric = (v.size() == 1) ? field : CartesianField();
0122       }
0123       if (isMag) {
0124         std::vector < CartesianField > &v = o->magnetic_components;
0125         v.emplace_back(field);
0126         o->field_type |= field.MAGNETIC;
0127         o->magnetic = (v.size() == 1) ? field : CartesianField();
0128       }
0129       if ( isMag || isEle )  {
0130         return;
0131       }
0132       except("OverlayedField","add: Attempt to add an unknown field type.");
0133     }
0134     except("OverlayedField","add: Attempt to add an invalid object.");
0135   }
0136   except("OverlayedField","add: Attempt to add an invalid field.");
0137 }
0138 
0139 /// Returns the 3  magnetic field components (x, y, z).
0140 void OverlayedField::magneticField(const Position& pos, double* field) const   {
0141   if ( isValid() )   {
0142     field[0] = field[1] = field[2] = 0.0;
0143     auto* obj = data<Object>();
0144     CartesianField f = obj->magnetic;
0145     if ( f.isValid() )
0146       f.value(pos, field);
0147     else
0148       calculate_combined_field(obj->magnetic_components, pos, field);
0149     return;
0150   }
0151   except("OverlayedField","add: Attempt to add an invalid field.");
0152 }
0153 
0154 /// Returns the 3 electric field components (x, y, z).
0155 void OverlayedField::combinedElectric(const Position& pos, double* field) const {
0156   field[0] = field[1] = field[2] = 0.;
0157   calculate_combined_field(data<Object>()->electric_components, pos, field);
0158 }
0159 
0160 /// Returns the 3  magnetic field components (x, y, z).
0161 void OverlayedField::combinedMagnetic(const Position& pos, double* field) const {
0162   field[0] = field[1] = field[2] = 0.;
0163   calculate_combined_field(data<Object>()->magnetic_components, pos, field);
0164 }
0165 
0166 /// Returns the 3 electric (val[0]-val[2]) and magnetic field components (val[3]-val[5]).
0167 void OverlayedField::electromagneticField(const Position& pos, double* field) const {
0168   Object* o = data<Object>();
0169   field[0] = field[1] = field[2] = 0.;
0170   calculate_combined_field(o->electric_components, pos, field);
0171   calculate_combined_field(o->magnetic_components, pos, field + 3);
0172 }