Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:16:57

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 // Framework include files
0015 #include <DD4hep/Grammar.h>
0016 #include <DD4hep/DetectorData.h>
0017 #include <DD4hep/InstanceCount.h>
0018 #include <DD4hep/detail/ObjectsInterna.h>
0019 #include <DD4hep/detail/DetectorInterna.h>
0020 
0021 // ROOT include files
0022 #include <TGeoManager.h>
0023 #include <TClassStreamer.h>
0024 #include <TDataMember.h>
0025 #include <TDataType.h>
0026 #include <TClass.h>
0027 #include <TROOT.h>
0028 
0029 namespace dd4hep {  namespace detail {    class DetectorImp;  }}
0030 
0031 using namespace dd4hep;
0032 
0033 namespace {
0034 
0035   union FundamentalData  {
0036     Char_t    c;
0037     Short_t   s;
0038     Int_t     i;
0039     Long_t    l;
0040     Float_t   f;
0041     Double_t  d;
0042     UChar_t   uc;
0043     UShort_t  us;
0044     UInt_t    ui;
0045     ULong_t   ul;
0046     Long64_t  ll;
0047     ULong64_t ull;
0048     Bool_t    b;
0049     void read(TBuffer& buff,int dtyp)   {
0050       switch(dtyp)  {
0051       case  1: buff >> c;    break;
0052       case  2: buff >> s;    break;
0053       case  3: buff >> i;    break;
0054       case  4: buff >> l;    break;
0055       case  5: buff >> f;    break;
0056       case  6: buff >> i;    break;
0057         //case  7: buff >> d;   break; // char*
0058       case  8: buff >> d;    break;
0059       case  9: buff >> d;    break;
0060       case 11: buff >> uc;   break;
0061       case 12: buff >> us;   break;
0062       case 13: buff >> ui;   break;
0063       case 14: buff >> ul;   break;
0064       case 15: buff >> ui;   break;
0065       case 16: buff >> ll;   break;
0066       case 17: buff >> ull;  break;
0067       case 18: buff >> b;    break;
0068       case 19: buff >> f;    break;
0069       default:
0070         printout(ERROR,"OpaqueData","Unknown fundamental data type: [%X]",dtyp);
0071         break;
0072       }
0073     }
0074     void write(TBuffer& buff,int dtyp)  const  {
0075       switch(dtyp)  {
0076       case  1: buff << c;    break;
0077       case  2: buff << s;    break;
0078       case  3: buff << i;    break;
0079       case  4: buff << l;    break;
0080       case  5: buff << f;    break;
0081       case  6: buff << i;    break;
0082         //case  7: buff << d;   break; // char*
0083       case  8: buff << d;    break;
0084       case  9: buff << d;    break;
0085       case 11: buff << uc;   break;
0086       case 12: buff << us;   break;
0087       case 13: buff << ui;   break;
0088       case 14: buff << ul;   break;
0089       case 15: buff << ui;   break;
0090       case 16: buff << ll;   break;
0091       case 17: buff << ull;  break;
0092       case 18: buff << b;    break;
0093       case 19: buff << f;    break;
0094       default:
0095         printout(ERROR,"OpaqueData","Unknown fundamental data type: [%X]",dtyp);
0096         break;
0097       }
0098     }
0099   };
0100 
0101   void stream_opaque_datablock(TBuffer& b, void* obj)    {
0102     UInt_t R__s = 0; // Start of object.
0103     UInt_t R__c = 0; // Count of bytes.
0104     TClass* cl = BasicGrammar::instance<OpaqueDataBlock>().clazz();//gROOT->GetClass("dd4hep::OpaqueDataBlock");
0105    
0106     OpaqueDataBlock* block = (OpaqueDataBlock*)obj;
0107     
0108     if ( b.IsReading() )  {
0109       b.ReadVersion(&R__s, &R__c, cl);
0110       BasicGrammar::key_type key = 0;
0111       b >> key;
0112       const BasicGrammar& gr = BasicGrammar::get(key);
0113       //printout(INFO,"OpaqueData","   Data type:%s  [%016llX]",gr.name.c_str(),key);
0114       void* ptr = block->ptr();
0115       if ( !ptr )  { // Some blocks are already bound. Skip those.
0116         if ( !gr.specialization.bind )   {
0117           except("stream_opaque_datablock","Object cannot be handled by ROOT persistency. "
0118                  "Grammar %s does not allow for ROOT persistency.",gr.type_name().c_str());
0119         }
0120         ptr = block->bind(&gr);
0121         gr.specialization.bind(ptr);
0122       }
0123       /// Now perform the I/O action
0124       if ( gr.type() == typeid(std::string) )
0125         b.ReadStdString(*(std::string*)ptr);
0126       else if ( gr.clazz() )
0127         b.ReadClassBuffer(gr.clazz(),ptr);
0128       else
0129         ((FundamentalData*)ptr)->read(b,gr.data_type());
0130       b.CheckByteCount(R__s, R__c, cl);
0131     }
0132     else if ( 0 == block->grammar )  {
0133       printout(ERROR,"OpaqueData","+++ ERROR +++ Opaque data block has no grammar attached. Cannot be saved!");
0134     }
0135     else  {
0136       const std::type_info& typ_info = typeid(*block);
0137       const BasicGrammar& gr = *block->grammar;
0138       std::string typ = gr.type_name();
0139 
0140       printout(DEBUG,"OpaqueData","Saving object %p type: %s [%s] [%s]",
0141            obj, typ_info.name(), typ.c_str(), block->grammar->name.c_str());
0142       R__c = b.WriteVersion(cl,kTRUE);
0143       b << gr.hash();
0144 
0145       /// Now perform the I/O action
0146       if ( gr.type() == typeid(std::string) )
0147         b.WriteStdString(*(std::string*)block->ptr());
0148       else if ( gr.clazz() )
0149         b.WriteClassBuffer(gr.clazz(),block->ptr());
0150       else
0151         ((const FundamentalData*)block->ptr())->write(b,gr.data_type());
0152       b.SetByteCount(R__c, kTRUE);
0153     }
0154   }
0155 }
0156 
0157 
0158 /// Default constructor
0159 DetectorData::DetectorData()
0160   : m_manager(0), m_world(), m_trackers(), m_worldVol(),
0161     m_trackingVol(), m_field(),
0162     m_buildType(BUILD_DEFAULT), m_extensions(typeid(DetectorData)), m_volManager(),
0163     m_inhibitConstants(false)
0164 {
0165   static bool first = true;
0166   if ( first )   {
0167     first = false;
0168     TClass* cl = gROOT->GetClass("dd4hep::OpaqueDataBlock");
0169     if ( 0 == cl )  {
0170       except("PersistencyIO","+++ Missing TClass for 'dd4hep::OpaqueDataBlock'.");
0171     }
0172     if ( 0 == cl->GetStreamer() )  {
0173       cl->AdoptStreamer(new TClassStreamer(stream_opaque_datablock));
0174       printout(INFO,"PersistencyIO","+++ Set Streamer to %s",cl->GetName());
0175     }
0176   }
0177   InstanceCount::increment(this);
0178 }
0179 
0180 /// Standard destructor
0181 DetectorData::~DetectorData() {
0182   clearData();
0183   InstanceCount::decrement(this);
0184 }
0185 
0186 /// Patch the ROOT streamers to adapt for DD4hep
0187 void DetectorData::patchRootStreamer(TClass* cl)   {
0188   TDataMember* dm = 0;
0189   printout(INFO,"PersistencyIO",
0190            "+++ Set data member %s.fUserExtension as PERSISTENT.",
0191            cl->GetName());
0192   dm = cl->GetDataMember("fUserExtension");
0193   dm->SetTitle(dm->GetTitle()+2);
0194   dm->SetBit(BIT(2));
0195 }
0196 
0197 /// UNPatch the ROOT streamers to adapt for DD4hep
0198 void DetectorData::unpatchRootStreamer(TClass* cl)   {
0199   TDataMember* dm = 0;
0200   printout(INFO,"PersistencyIO",
0201            "+++ Set data member %s.fUserExtension as TRANSIENT.",
0202            cl->GetName());
0203   dm = cl->GetDataMember("fUserExtension");
0204   dm->SetTitle((std::string("! ")+dm->GetTitle()).c_str());
0205   dm->ResetBit(BIT(2));
0206 }
0207 
0208 /// Clear data content: releases all allocated resources
0209 void DetectorData::destroyData(bool destroy_mgr)   {
0210   m_extensions.clear();
0211   m_detectorParents.clear();
0212 
0213   detail::destroyHandle(m_world);
0214   detail::destroyHandle(m_field);
0215   detail::destroyHandle(m_header);
0216   detail::destroyHandles(m_readouts);
0217   detail::destroyHandles(m_idDict);
0218   detail::destroyHandles(m_limits);
0219   detail::destroyHandles(m_regions);
0220   detail::destroyHandles(m_sensitive);
0221   detail::destroyHandles(m_display);
0222   detail::destroyHandles(m_fields);
0223   detail::destroyHandles(m_define);
0224 #if 0
0225   for(const auto& def : m_define)   {
0226     auto c = def;
0227     std::cout << "Delete " << def.first << std::endl;
0228     //if ( def.first == "world_side" ) continue;
0229     delete def.second.ptr();
0230   }
0231 #endif  
0232   detail::destroyHandle(m_volManager);
0233   m_properties.clear();
0234   m_trackers.clear();
0235   m_trackingVol.clear();
0236   m_parallelWorldVol.clear();
0237   m_worldVol.clear();
0238   m_invisibleVis.clear();
0239   m_materialVacuum.clear();
0240   m_materialAir.clear();
0241   m_inhibitConstants = false;
0242   if ( destroy_mgr )  {
0243     gGeoManager = m_manager;
0244     detail::deletePtr(m_manager);
0245     gGeoManager = 0;
0246   }
0247   else  {
0248     gGeoManager = m_manager;
0249     m_manager = 0;
0250   }
0251 }
0252 
0253 
0254 /// Clear data content: releases all allocated resources
0255 void DetectorData::clearData()   {
0256   m_extensions.clear(false);
0257   m_detectorParents.clear();
0258   m_world.clear();
0259   m_field.clear();
0260   m_header.clear();
0261   m_properties.clear();
0262   m_readouts.clear();
0263   m_idDict.clear();
0264   m_limits.clear();
0265   m_regions.clear();
0266   m_sensitive.clear();
0267   m_display.clear();
0268   m_fields.clear();
0269   m_define.clear();
0270   m_trackers.clear();
0271   m_worldVol.clear();
0272   m_trackingVol.clear();
0273   m_parallelWorldVol.clear();
0274   m_invisibleVis.clear();
0275   m_materialVacuum.clear();
0276   m_materialAir.clear();
0277   m_volManager.clear();
0278   m_manager = 0;
0279   m_inhibitConstants = false;
0280 }
0281 
0282 /// Adopt all data from source structure
0283 void DetectorData::adoptData(DetectorData& source, bool clr)   {
0284   m_inhibitConstants   = source.m_inhibitConstants;
0285   m_extensions.move(source.m_extensions);
0286   m_manager            = source.m_manager;
0287   m_readouts           = source.m_readouts;
0288   m_idDict             = source.m_idDict;
0289   m_limits             = source.m_limits;
0290   m_regions            = source.m_regions;
0291   m_detectors          = source.m_detectors;
0292   m_sensitive          = source.m_sensitive;
0293   m_display            = source.m_display;
0294   m_fields             = source.m_fields;
0295   m_define             = source.m_define;
0296 
0297   m_detectorParents    = source.m_detectorParents;
0298   m_world              = source.m_world;
0299   World w              = m_world;
0300   w->description       = dynamic_cast<Detector*>(this);
0301   m_trackers           = source.m_trackers;
0302   m_worldVol           = source.m_worldVol;
0303   m_trackingVol        = source.m_trackingVol;
0304   m_parallelWorldVol   = source.m_parallelWorldVol;
0305   m_materialAir        = source.m_materialAir;
0306   m_materialVacuum     = source.m_materialVacuum;
0307   m_invisibleVis       = source.m_invisibleVis;
0308   m_field              = source.m_field;
0309   m_header             = source.m_header;
0310   m_properties         = source.m_properties;
0311   //m_extensions       = source.m_extensions;
0312   m_volManager         = source.m_volManager;
0313 
0314   // Update world element
0315   m_world.setPlacement(m_manager->GetTopNode());
0316   // Need to update some global stuff
0317   if ( gGeoManager != m_manager ) delete gGeoManager;
0318   gGeoManager         = m_manager;
0319   if ( clr ) source.clearData();
0320 }