TYPE* _create_share(Geant4Kernel& kernel, CONT& (Geant4ActionContainer::*pmf)(), const string& type_name, const string& shared_typ, bool shared, TYPE*) { TypeName typ = TypeName::split(type_name); Geant4Kernel& k = shared ? kernel.master() : kernel; if ( shared && k.isMultiThreaded() ) { typedef typename TYPE::shared_type _ST; TypeName s_type = TypeName::split(shared_typ+"/"+typ.second); _ST* object = (_ST*)_create_object<TYPE>(kernel,s_type); CONT& container = (k.*pmf)(); TYPE* value = 0; { // Need to protect the global action sequence! G4AutoLock protection_lock(&creation_mutex); value = container.get(typ.second); if ( !value ) { value = _create_object<TYPE>(k,typ); container.adopt(value); value->release(); } } object->use(value); value->info("+++ Created shared object for %s of type %s.", typ.second.c_str(),typeName(typeid(TYPE)).c_str()); return object; } TYPE* value = _create_object<TYPE>(k,typ); return value; }
/// Instantiate Geant4 sensitive detectors and electro-magnetic field void Geant4UserDetectorConstruction::ConstructSDandField() { G4AutoLock protection_lock(&action_mutex); Geant4Context* ctx = m_sequence->context(); Geant4Kernel& krnl = kernel().worker(Geant4Kernel::thread_self(),true); updateContext(krnl.workerContext()); m_sequence->constructField(&m_ctxt); m_sequence->constructSensitives(&m_ctxt); updateContext(ctx); }
/// Construct electro magnetic field entity from the DD4hep field G4VPhysicalVolume* Geant4UserDetectorConstruction::Construct() { // The G4TransportationManager is thread-local. // Thus, regardless of whether the field class object is global or local // to a certain volume, a field object must be assigned to G4FieldManager. G4AutoLock protection_lock(&action_mutex); updateContext(m_sequence->context()); m_sequence->constructGeo(&m_ctxt); if ( 0 == m_ctxt.world ) { m_sequence->except("+++ Executing G4 detector construction did not result in a valid world volume!"); } return m_ctxt.world; }
/// Build the actions for the worker thread void Geant4UserActionInitialization::Build() const { G4AutoLock protection_lock(&action_mutex); Geant4Kernel& krnl = kernel().worker(Geant4Kernel::thread_self(),true); Geant4Context* ctx = krnl.workerContext(); if ( m_sequence ) { Geant4Context* old = m_sequence->context(); m_sequence->info("+++ Executing Geant4UserActionInitialization::Build. " "Context:%p Kernel:%p [%ld]", (void*)ctx, (void*)&krnl, krnl.id()); m_sequence->updateContext(ctx); m_sequence->build(); m_sequence->updateContext(old); } // Set user generator action sequence. Not optional, since event context is defined inside Geant4UserGeneratorAction* gen_action = new Geant4UserGeneratorAction(ctx,krnl.generatorAction(false)); SetUserAction(gen_action); // Set the run action sequence. Not optional, since run context is defined/destroyed inside Geant4UserRunAction* run_action = new Geant4UserRunAction(ctx,krnl.runAction(false)); SetUserAction(run_action); // Set the event action sequence. Not optional, since event context is destroyed inside Geant4UserEventAction* evt_action = new Geant4UserEventAction(ctx,krnl.eventAction(false)); run_action->eventAction = evt_action; evt_action->runAction = run_action; SetUserAction(evt_action); // Set the tracking action sequence Geant4TrackingActionSequence* trk_action = krnl.trackingAction(false); if ( trk_action ) { Geant4UserTrackingAction* action = new Geant4UserTrackingAction(ctx, trk_action); SetUserAction(action); } // Set the stepping action sequence Geant4SteppingActionSequence* stp_action = krnl.steppingAction(false); if ( stp_action ) { Geant4UserSteppingAction* action = new Geant4UserSteppingAction(ctx, stp_action); SetUserAction(action); } // Set the stacking action sequence Geant4StackingActionSequence* stk_action = krnl.stackingAction(false); if ( stk_action ) { Geant4UserStackingAction* action = new Geant4UserStackingAction(ctx, stk_action); SetUserAction(action); } }