Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:17:24

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 #define DDG4_MAKE_INSTANTIATIONS
0016 #include <DD4hep/Detector.h>
0017 #include <DD4hep/Printout.h>
0018 #include <DDG4/Geant4HitCollection.h>
0019 #include <DDG4/Geant4DataConversion.h>
0020 #include <DDG4/Geant4SensDetAction.h>
0021 #include <DDG4/Geant4Context.h>
0022 #include <DDG4/Geant4Primary.h>
0023 #include <DDG4/Geant4Data.h>
0024 
0025 // LCIO includes
0026 #include <lcio.h>
0027 #include <IMPL/LCCollectionVec.h>
0028 //
0029 #include <IMPL/LCEventImpl.h>
0030 #include <IMPL/ClusterImpl.h>
0031 #include <IMPL/SimTrackerHitImpl.h>
0032 #include <IMPL/SimCalorimeterHitImpl.h>
0033 #include <IMPL/MCParticleImpl.h>
0034 //
0035 #include <UTIL/Operators.h>
0036 #include <UTIL/ILDConf.h>
0037 
0038 #include <CLHEP/Units/SystemOfUnits.h>
0039 
0040 using namespace std;
0041 using namespace lcio ;
0042 //==================================================================================
0043 //
0044 // SimCalorimeterHit:
0045 // ------------------
0046 // LCIO::CHBIT_STEP       If detailed mode set                    | YES if detailed
0047 // LCIO::CHBIT_LONG:      Position is stored                      | YES
0048 // LCIO::CHBIT_ID1:       CellID1 is stored                       | YES
0049 //
0050 //
0051 // SimTrackerHit:
0052 // --------------
0053 // LCIO::THBIT_ID1:       CellID1 is stored (TrackerHit)          | YES
0054 // LCIO::THBIT_MOMENTUM:  Momentum is stored                      | YES if detailed
0055 //
0056 //==================================================================================
0057 
0058 /*
0059  *   dd4hep namespace declaration
0060  */
0061 namespace dd4hep {
0062 
0063   /*
0064    *   Simulation namespace declaration
0065    */
0066   namespace sim   {
0067 
0068     typedef VolumeManager VolMgr;
0069     typedef IDDescriptor  IDDescriptor;
0070 
0071     /// Data conversion interface calling lower level explicit convetrers
0072     /**
0073      *  @author M.Frank
0074      *  @version 1.0
0075      */
0076     template <> lcio::LCCollectionVec*
0077     Geant4DataConversion<lcio::LCCollectionVec,
0078                          pair<const Geant4Context*,G4VHitsCollection*>,
0079                          Geant4HitCollection>::operator()(const arg_t& args)  const {
0080       G4VHitsCollection* c = args.second;
0081       Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(c);
0082       if ( coll )  {
0083         typedef pair<arg_t::first_type,Geant4HitCollection*> _A;
0084         typedef Geant4Conversion<output_t,_A> _C;
0085         const _C& cnv= _C::converter(coll->type().type());
0086         return cnv(_A(args.first,coll));
0087       }
0088       throw unrelated_type_error(typeid(Geant4HitCollection),typeid(*c),
0089                                  "Cannot save the collection entries of:"+c->GetName());
0090     }
0091 
0092     /// Data conversion interface creating lcio::SimTrackerHitImpl from Geant4Tracker::Hit structures
0093     /**
0094      *  This converter is to be used, when the sensitive detectors create fill collections
0095      *  of type Geant4HitCollection with objects of type **Geant4Tracker::Hit**.
0096      *  The original objects are untouched and are automatically when the hosting
0097      *  Geant4HitCollection object is released.
0098      *
0099      *  @author M.Frank
0100      *  @version 1.0
0101      */
0102     template <> lcio::LCCollectionVec*
0103     Geant4DataConversion<lcio::LCCollectionVec,
0104                          pair<const Geant4Context*,Geant4HitCollection*>,
0105                          Geant4Tracker::Hit>::operator()(const arg_t& args)  const   {
0106 
0107       Geant4HitCollection*   coll    = args.second;
0108       string                 hc_nam  = coll->GetName();
0109       Geant4Sensitive*       sd      = coll->sensitive();
0110       size_t                 nhits   = coll->GetSize();
0111       string                 dsc     = encoding(sd->sensitiveDetector());
0112       Geant4ParticleMap*     pm      = args.first->event().extension<Geant4ParticleMap>();
0113       lcio::LCEventImpl*     lc_evt  = args.first->event().extension<lcio::LCEventImpl>();
0114       EVENT::LCCollection*   lc_part = lc_evt->getCollection(lcio::LCIO::MCPARTICLE);
0115       lcio::LCCollectionVec* lc_coll = nullptr;
0116       bool isNewCollection           = false;
0117       try {
0118         lc_coll = static_cast<lcio::LCCollectionVec*>(lc_evt->getCollection(hc_nam));
0119       } catch (lcio::DataNotAvailableException &e) {
0120         lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMTRACKERHIT);
0121         isNewCollection = true;
0122       }
0123       UTIL::CellIDEncoder<SimTrackerHit> decoder(dsc,lc_coll);
0124       int hit_creation_mode = sd->hitCreationMode();
0125 
0126       if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )
0127         lc_coll->setFlag(UTIL::make_bitset32(LCIO::THBIT_MOMENTUM,LCIO::THBIT_ID1));
0128       else
0129         lc_coll->setFlag(LCIO::THBIT_ID1);
0130 
0131       lc_coll->reserve(nhits + lc_coll->getNumberOfElements());
0132       for(size_t i=0; i<nhits; ++i)   {
0133         const Geant4Tracker::Hit* hit = coll->hit(i);
0134         const Geant4Tracker::Hit::Contribution& t = hit->truth;
0135         int trackID = pm->particleID(t.trackID);
0136         EVENT::MCParticle* lc_mcp = (EVENT::MCParticle*)lc_part->getElementAt(trackID);
0137         double pos[3] = {hit->position.x()/CLHEP::mm, hit->position.y()/CLHEP::mm, hit->position.z()/CLHEP::mm};
0138         lcio::SimTrackerHitImpl* lc_hit = new lcio::SimTrackerHitImpl;
0139         lc_hit->setCellID0((hit->cellID >>    0         ) & 0xFFFFFFFF);
0140         lc_hit->setCellID1((hit->cellID >> sizeof(int)*8) & 0xFFFFFFFF);
0141         lc_hit->setEDep(hit->energyDeposit/CLHEP::GeV);
0142         lc_hit->setPathLength(hit->length/CLHEP::mm);
0143         lc_hit->setTime(hit->truth.time/CLHEP::ns);
0144         lc_hit->setMCParticle(lc_mcp);
0145         lc_hit->setPosition(pos);
0146         lc_hit->setMomentum(hit->momentum.x()/CLHEP::GeV,hit->momentum.y()/CLHEP::GeV,hit->momentum.z()/CLHEP::GeV);
0147 
0148 #if LCIO_VERSION_GE( 2, 8 )
0149         auto particleIt = pm->particles().find(trackID);
0150         if( ( particleIt != pm->particles().end()) ){
0151       // if the original track ID of the particle is not the same as the
0152       // original track ID of the hit it was produced by an MCParticle that
0153       // is no longer stored
0154       lc_hit->setProducedBySecondary( (particleIt->second->originalG4ID != t.trackID) );
0155         }
0156 #endif
0157         lc_coll->addElement(lc_hit);
0158       }
0159 
0160       if(isNewCollection) {
0161         lc_evt->addCollection(lc_coll, hc_nam);
0162       }
0163       return lc_coll;
0164     }
0165 
0166     /// Data conversion interface creating lcio::SimCalorimeterHitImpl from Geant4Calorimeter::Hit structures
0167     /**
0168      *  This converter is to be used, when the sensitive detectors create fill collections
0169      *  of type Geant4HitCollection with objects of type **Geant4Calorimeter::Hit**.
0170      *  The original objects are untouched and are automatically when the hosting
0171      *  Geant4HitCollection object is released.
0172      *
0173      *  @author M.Frank
0174      *  @version 1.0
0175      */
0176     template <> lcio::LCCollectionVec*
0177     Geant4DataConversion<lcio::LCCollectionVec,
0178                          pair<const Geant4Context*,Geant4HitCollection*>,
0179                          Geant4Calorimeter::Hit>::operator()(const arg_t& args)  const  {
0180       typedef Geant4HitData::Contributions Contributions;
0181       Geant4HitCollection*   coll     = args.second;
0182       string                 hc_nam   = coll->GetName();
0183       Geant4Sensitive*       sd       = coll->sensitive();
0184       size_t                 nhits    = coll->GetSize();
0185       string                 dsc      = encoding(sd->sensitiveDetector());
0186       Geant4ParticleMap*     pm       = args.first->event().extension<Geant4ParticleMap>();
0187       lcio::LCEventImpl*     lc_evt   = args.first->event().extension<lcio::LCEventImpl>();
0188       EVENT::LCCollection*   lc_parts = lc_evt->getCollection(lcio::LCIO::MCPARTICLE);
0189       lcio::LCCollectionVec* lc_coll  = nullptr;
0190       bool isNewCollection            = false;
0191       try {
0192         lc_coll = static_cast<lcio::LCCollectionVec*>(lc_evt->getCollection(hc_nam));
0193       } catch (lcio::DataNotAvailableException &e) {
0194         lc_coll = new lcio::LCCollectionVec(lcio::LCIO::SIMCALORIMETERHIT);
0195         isNewCollection = true;
0196       }
0197       UTIL::CellIDEncoder<SimCalorimeterHit> decoder(dsc,lc_coll);
0198       int hit_creation_mode = sd->hitCreationMode();
0199 
0200       if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )
0201         lc_coll->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_STEP,LCIO::CHBIT_ID1));
0202       else
0203         lc_coll->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_ID1));
0204 
0205       lc_coll->reserve(nhits + lc_coll->getNumberOfElements());
0206       if ( sd->hasProperty("HitCreationMode") )  {
0207         hit_creation_mode = sd->property("HitCreationMode").value<int>();
0208       }
0209       for(size_t i=0; i<nhits; ++i)   {
0210         const Geant4Calorimeter::Hit* hit = coll->hit(i);
0211         float pos[3] = {float(hit->position.x()/CLHEP::mm), float(hit->position.y()/CLHEP::mm), float(hit->position.z()/CLHEP::mm)};
0212         lcio::SimCalorimeterHitImpl*  lc_hit = new lcio::SimCalorimeterHitImpl;
0213         lc_hit->setCellID0((hit->cellID >>    0         ) & 0xFFFFFFFF);
0214         lc_hit->setCellID1((hit->cellID >> sizeof(int)*8) & 0xFFFFFFFF); // ????
0215         lc_hit->setPosition(pos);
0216         ///No! Done when adding particle contributions: lc_hit->setEnergy( hit->energyDeposit );
0217         lc_coll->addElement(lc_hit);
0218         /// Now add the individual track contributions to the LCIO hit structure
0219         for(Contributions::const_iterator j=hit->truth.begin(); j!=hit->truth.end(); ++j)   {
0220           const Geant4HitData::Contribution& c = *j;
0221           int trackID = pm->particleID(c.trackID);
0222           EVENT::MCParticle* lc_mcp = (EVENT::MCParticle*)lc_parts->getElementAt(trackID);
0223           if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )     {
0224             float contrib_pos[] = {float(c.x/CLHEP::mm), float(c.y/CLHEP::mm), float(c.z/CLHEP::mm)};
0225 #if LCIO_VERSION_GE( 2, 11 )
0226             lc_hit->addMCParticleContribution(lc_mcp, c.deposit/CLHEP::GeV, c.time/CLHEP::ns, c.length/CLHEP::mm, c.pdgID, contrib_pos);
0227 #else
0228             lc_hit->addMCParticleContribution(lc_mcp, c.deposit/CLHEP::GeV, c.time/CLHEP::ns, c.pdgID, contrib_pos);
0229 #endif
0230           }
0231           else    {
0232             lc_hit->addMCParticleContribution(lc_mcp, c.deposit/CLHEP::GeV, c.time/CLHEP::ns);
0233           }
0234         }
0235       }
0236       if(isNewCollection) {
0237         lc_evt->addCollection(lc_coll, hc_nam);
0238       }
0239       return lc_coll;
0240     }
0241 
0242     template <typename T>
0243     lcio::LCCollectionVec* moveEntries(Geant4HitCollection* coll,
0244                                        lcio::LCCollectionVec* lc_coll)
0245     {
0246       size_t nhits = coll->GetSize();
0247       lc_coll->reserve(nhits);
0248       for(size_t i=0; i<nhits; ++i)   {
0249         Geant4HitWrapper& wrap = coll->hit(i);
0250         T* lc_hit = wrap;
0251         wrap.release();  // Now we have ownership!
0252         lc_coll->addElement(lc_hit);
0253       }
0254       coll->clear(); // Since the collection now only contains NULL pointers, better clear it!
0255       return lc_coll;
0256     }
0257 
0258     /// Data conversion interface moving lcio::SimTrackerHitImpl objects from a Geant4HitCollection to a LCCollectionVec
0259     /**
0260      *  This converter is to be used, when the sensitive detectors create fill collections
0261      *  of type Geant4HitCollection with objects of type **lcio::SimTrackerHitImpl**.
0262      *  The ownership of the original Geant4HitCollection is released and moved to
0263      *  the newly created lcio::LCCollectionVec container.
0264      *  Finally the original hits collection is cleared.
0265      *
0266      *  Note: This conversion is INTRUSIVE and CLEARS the original collection!
0267      *
0268      *  @author M.Frank
0269      *  @version 1.0
0270      */
0271     template <> lcio::LCCollectionVec*
0272     Geant4DataConversion<lcio::LCCollectionVec,
0273                          pair<const Geant4Context*,Geant4HitCollection*>,
0274                          lcio::SimTrackerHitImpl>::operator()(const arg_t& args)  const
0275     {
0276       Geant4Sensitive* sd  = args.second->sensitive();
0277       string           dsc = encoding(sd->sensitiveDetector());
0278       output_t*        lc  = new lcio::LCCollectionVec(lcio::LCIO::SIMTRACKERHIT);
0279       int hit_creation_mode = sd->hitCreationMode();
0280 
0281       if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )
0282         lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_STEP,LCIO::CHBIT_ID1));
0283       else
0284         lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_ID1));
0285       UTIL::CellIDEncoder<SimTrackerHit> decoder(dsc,lc);
0286       return moveEntries<lcio::SimTrackerHitImpl>(args.second,lc);
0287     }
0288 
0289     /// Data conversion interface moving lcio::SimCalorimeterHitImpl objects from a Geant4HitCollection to a LCCollectionVec
0290     /**
0291      *  This converter is to be used, when the sensitive detectors create fill collections
0292      *  of type Geant4HitCollection with objects of type **lcio::SimCalorimeterHitImpl**.
0293      *  The ownership of the original Geant4HitCollection is released and moved to
0294      *  the newly created lcio::LCCollectionVec container.
0295      *  Finally the original hits collection is cleared.
0296      *
0297      *  Note: This conversion is INTRUSIVE and CLEARS the original collection!
0298      *
0299      *  @author M.Frank
0300      *  @version 1.0
0301      */
0302     template <> lcio::LCCollectionVec*
0303     Geant4DataConversion<lcio::LCCollectionVec,
0304                          pair<const Geant4Context*,Geant4HitCollection*>,
0305                          lcio::SimCalorimeterHitImpl>::operator()(const arg_t& args)  const
0306     {
0307       Geant4Sensitive*  sd  = args.second->sensitive();
0308       //string          dsc = encoding(args.second->sensitive()->sensitiveDetector());
0309       output_t*         lc  = new lcio::LCCollectionVec(lcio::LCIO::SIMCALORIMETERHIT);
0310       int hit_creation_mode = sd->hitCreationMode();
0311 
0312       if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE )
0313         lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_STEP,LCIO::CHBIT_ID1));
0314       else
0315         lc->setFlag(UTIL::make_bitset32(LCIO::CHBIT_LONG,LCIO::CHBIT_ID1));
0316       return moveEntries<tag_t>(args.second,lc);
0317     }
0318 
0319     /// Data conversion interface moving lcio::ClusterImpl objects from a Geant4HitCollection to a LCCollectionVec
0320     /** Same comments apply as for the data mover for lcio::SimCalorimeterHitImpl and lcio::SimTrackerHitImpl
0321      *
0322      *  @author M.Frank
0323      *  @version 1.0
0324      */
0325     template <> lcio::LCCollectionVec*
0326     Geant4DataConversion<lcio::LCCollectionVec,
0327                          pair<const Geant4Context*,Geant4HitCollection*>,
0328                          lcio::ClusterImpl>::operator()(const arg_t& args)  const
0329     {
0330       output_t* lc = new lcio::LCCollectionVec(lcio::LCIO::CLUSTER);
0331       return moveEntries<tag_t>(args.second,lc);
0332     }
0333 
0334     typedef pair<const Geant4Context*,G4VHitsCollection*> RAW_CONVERSION_ARGS;
0335     typedef pair<const Geant4Context*,Geant4HitCollection*> CONVERSION_ARGS;
0336     template class Geant4Conversion<lcio::LCCollectionVec,RAW_CONVERSION_ARGS>;
0337     DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,RAW_CONVERSION_ARGS,Geant4HitCollection)
0338 
0339     template class Geant4Conversion<lcio::LCCollectionVec,CONVERSION_ARGS>;
0340     // Hit converters for simple Geant4Data objects
0341     DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,Geant4Tracker::Hit)
0342     DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,Geant4Calorimeter::Hit)
0343     // Hit converters for standard LCIO objects
0344     DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::SimTrackerHitImpl)
0345     DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::SimCalorimeterHitImpl)
0346     DECLARE_GEANT4_HITCONVERTER(lcio::LCCollectionVec,CONVERSION_ARGS,lcio::ClusterImpl)
0347   }    // End namespace sim
0348 }      // End namespace dd4hep
0349 
0350 
0351