zoukankan      html  css  js  c++  java
  • geant4 灵敏探测器

    geant4 灵敏探测器


     如何模拟探测器的响应?

    1. SteppingAction 统计每一个 step 在探测器中沉积的能量。
    2. 指定探测器为灵敏探测器,统计探测器内每一个 step 的能量沉积。

    如何设置一个灵敏探测器?

    1. 指定某逻辑体为灵敏探测器
    2. 将灵敏探测器纳入 SD 管理器

      代码举例,取自 example B2a ---- 设置灵敏探测器,将灵敏探测器纳入 SD 管理器,指定某逻辑体为灵敏探测器。

     1 void B2aDetectorConstruction::ConstructSDandField()
     2 {
     3   // Sensitive detectors
     4 
     5   G4String trackerChamberSDname = "B2/TrackerChamberSD";
     6   B2TrackerSD* aTrackerSD = new B2TrackerSD(trackerChamberSDname,
     7                                             "TrackerHitsCollection");
     8   G4SDManager::GetSDMpointer()->AddNewDetector(aTrackerSD);
     9   // Setting aTrackerSD to all logical volumes with the same name 
    10   // of "Chamber_LV".
    11   SetSensitiveDetector("Chamber_LV", aTrackerSD, true);
    12 
    13   // Create global magnetic field messenger.
    14   // Uniform magnetic field is then created automatically if
    15   // the field value is not zero.
    16   G4ThreeVector fieldValue = G4ThreeVector();
    17   fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue);
    18   fMagFieldMessenger->SetVerboseLevel(1);
    19   
    20   // Register the field messenger for deleting
    21   G4AutoDelete::Register(fMagFieldMessenger);
    22 }
    • 第 6 - 9 行,设置灵敏探测器, 并将其纳入灵敏探测器管理器。其中 “TrackerHitsCollection” 是设置的 hitcollectionName,便于在 G4HCofThisEvent 容器中索引。
    • 第 11 行,使用 方法 SetSensitiveDetector()设置逻辑体为灵敏探测器,该方法的构造函数如下,这里是将所有名字为 Chamber_LV 的逻辑体统统设置为灵敏探测器。
      void SetSensitiveDetector(const G4String& logVolName,
                      G4VSensitiveDetector* aSD,G4bool multi=false);
      void SetSensitiveDetector(G4LogicalVolume* logVol,
                      G4VSensitiveDetector* aSD);

    如何从灵敏探测器中提取信息?

    Hit、HitCollection、Event

    • Hit:记录 SD 中每个 G4Step 中的信息(能量,时间等),因此一个 SD 中将产生大量Hit对象。
    • HitCollection:一个 SD 中产生大量的 Hit,可以被记录在一个或者多个容器中, 该容器即为 HitCollection 对象。
    • G4HCofThisEvent:G4Event 的一个成员对象,为一容器;多个 SD 的多个 HitCollection 对象储存在该容器中。

    一个 Hit 类的举例,代码取自 example B2a

     1 /// Tracker hit class
     2 ///
     3 /// It defines data members to store the trackID, chamberNb, energy deposit,
     4 /// and position of charged particles in a selected volume:
     5 /// - fTrackID, fChamberNB, fEdep, fPos
     6 
     7 class B2TrackerHit : public G4VHit
     8 {
     9   public:
    10     B2TrackerHit();
    11     B2TrackerHit(const B2TrackerHit&);
    12     virtual ~B2TrackerHit();
    13 
    14     // operators
    15     const B2TrackerHit& operator=(const B2TrackerHit&);
    16     G4int operator==(const B2TrackerHit&) const;
    17 
    18     inline void* operator new(size_t);
    19     inline void  operator delete(void*);
    20 
    21     // methods from base class
    22     virtual void Draw();
    23     virtual void Print();
    24 
    25     // Set methods
    26     void SetTrackID  (G4int track)      { fTrackID = track; };
    27     void SetChamberNb(G4int chamb)      { fChamberNb = chamb; };
    28     void SetEdep     (G4double de)      { fEdep = de; };
    29     void SetPos      (G4ThreeVector xyz){ fPos = xyz; };
    30 
    31     // Get methods
    32     G4int GetTrackID() const     { return fTrackID; };
    33     G4int GetChamberNb() const   { return fChamberNb; };
    34     G4double GetEdep() const     { return fEdep; };
    35     G4ThreeVector GetPos() const { return fPos; };
    36 
    37   private:
    38 
    39       G4int         fTrackID;
    40       G4int         fChamberNb;
    41       G4double      fEdep;
    42       G4ThreeVector fPos;
    43 };
    44 
    45 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    46 
    47 typedef G4THitsCollection<B2TrackerHit> B2TrackerHitsCollection;
    48 
    49 extern G4ThreadLocal G4Allocator<B2TrackerHit>* B2TrackerHitAllocator;
    50 
    51 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    52 
    53 inline void* B2TrackerHit::operator new(size_t)
    54 {
    55   if(!B2TrackerHitAllocator)
    56       B2TrackerHitAllocator = new G4Allocator<B2TrackerHit>;
    57   return (void *) B2TrackerHitAllocator->MallocSingle();
    58 }
    59 
    60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    61 
    62 inline void B2TrackerHit::operator delete(void *hit)
    63 {
    64   B2TrackerHitAllocator->FreeSingle((B2TrackerHit*) hit);
    65 }
    • 在上述例子中,提取了 tarckID,Chamber number,沉积能量,位置信息。
    • 选择在 hit 中记录哪些量,是在 hit 类中明确的。
    • 第 47 行,将存放 B2TrackerHit 的容器类型重命名为 B2TrackerHitsCollection,方便接下来定义使用。

    一个 SD 类的举例,代码取自 example B2a

     1 #ifndef B2TrackerSD_h
     2 #define B2TrackerSD_h 1
     3 
     4 #include "G4VSensitiveDetector.hh"
     5 
     6 #include "B2TrackerHit.hh"
     7 
     8 #include <vector>
     9 
    10 class G4Step;
    11 class G4HCofThisEvent;
    12 
    13 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    14 
    15 /// B2Tracker sensitive detector class
    16 ///
    17 /// The hits are accounted in hits in ProcessHits() function which is called
    18 /// by Geant4 kernel at each step. A hit is created with each step with non zero 
    19 /// energy deposit.
    20 
    21 class B2TrackerSD : public G4VSensitiveDetector
    22 {
    23   public:
    24     B2TrackerSD(const G4String& name, 
    25                 const G4String& hitsCollectionName);
    26     virtual ~B2TrackerSD();
    27   
    28     // methods from base class
    29     virtual void   Initialize(G4HCofThisEvent* hitCollection);
    30     virtual G4bool ProcessHits(G4Step* step, G4TouchableHistory* history);
    31     virtual void   EndOfEvent(G4HCofThisEvent* hitCollection);
    32 
    33   private:
    34     B2TrackerHitsCollection* fHitsCollection;
    35 };
    36 
    37 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    38 
    39 #endif
     1 #include "B2TrackerSD.hh"
     2 #include "G4HCofThisEvent.hh"
     3 #include "G4Step.hh"
     4 #include "G4ThreeVector.hh"
     5 #include "G4SDManager.hh"
     6 #include "G4ios.hh"
     7 
     8 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     9 
    10 B2TrackerSD::B2TrackerSD(const G4String& name,
    11                          const G4String& hitsCollectionName) 
    12  : G4VSensitiveDetector(name),
    13    fHitsCollection(NULL)
    14 {
    15   collectionName.insert(hitsCollectionName);
    16 }
    17 
    18 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    19 
    20 B2TrackerSD::~B2TrackerSD() 
    21 {}
    22 
    23 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    24 
    25 void B2TrackerSD::Initialize(G4HCofThisEvent* hce)
    26 {
    27   // Create hits collection
    28 
    29   fHitsCollection 
    30     = new B2TrackerHitsCollection(SensitiveDetectorName, collectionName[0]); 
    31 
    32   // Add this collection in hce
    33 
    34   G4int hcID 
    35     = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
    36   hce->AddHitsCollection( hcID, fHitsCollection ); 
    37 }
    38 
    39 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    40 
    41 G4bool B2TrackerSD::ProcessHits(G4Step* aStep, 
    42                                      G4TouchableHistory*)
    43 {  
    44   // energy deposit
    45   G4double edep = aStep->GetTotalEnergyDeposit();
    46 
    47   if (edep==0.) return false;
    48 
    49   B2TrackerHit* newHit = new B2TrackerHit();
    50 
    51   newHit->SetTrackID  (aStep->GetTrack()->GetTrackID());
    52   newHit->SetChamberNb(aStep->GetPreStepPoint()->GetTouchableHandle()
    53                                                ->GetCopyNumber());
    54   newHit->SetEdep(edep);
    55   newHit->SetPos (aStep->GetPostStepPoint()->GetPosition());
    56 
    57   fHitsCollection->insert( newHit );
    58 
    59   //newHit->Print();
    60 
    61   return true;
    62 }
    63 
    64 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    65 
    66 void B2TrackerSD::EndOfEvent(G4HCofThisEvent*)
    67 {
    68   if ( verboseLevel>1 ) { 
    69      G4int nofHits = fHitsCollection->entries();
    70      G4cout << G4endl
    71             << "-------->Hits Collection: in this event they are " << nofHits 
    72             << " hits in the tracker chambers: " << G4endl;
    73      for ( G4int i=0; i<nofHits; i++ ) (*fHitsCollection)[i]->Print();
    74   }
    75 }
    76 
    77 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    • 当一个 step 的能量沉积不是 0 的时候,就会创建一个 hit,言外之意是,不是所有的 step 都有能量沉积。
    • 灵敏探测器类继承自 G4VSensitiveDetector 类,其中必须实现的方法是 ProcessHits(G4Step*aStep,G4TouchableHistory*ROhist) ,该方法是从 step 中提取信息,写入 hit 中,并且将 hit 放入到 HitCollection 的容器中。
    • 第 15 行,必须要设置 "collectionName" string vector,原文:In the derived class constructor, name(s) of hits collection(s) which are made by the sensitive detector must be set to "collectionName" string vector. 
    • EndOfEvent(G4HCofThisEvent*) 不是一定要实现的方法,在该例中,在 EndOfEvent() 方法中提取了每一个 Event 共产生了多少个hit.

    一个 EventAction 类的举例,用于提取灵敏探测器的信息,代码取自 example B5(第一段代码取自 DetectorConstruction.cc)

     1 void B5DetectorConstruction::ConstructSDandField()
     2 {
     3   // sensitive detectors -----------------------------------------------------
     4   auto sdManager = G4SDManager::GetSDMpointer();
     5   G4String SDname;
     6   
     7   auto hodoscope1 = new B5HodoscopeSD(SDname="/hodoscope1");
     8   sdManager->AddNewDetector(hodoscope1);
     9   fHodoscope1Logical->SetSensitiveDetector(hodoscope1);
    10 
    11   auto hodoscope2 = new B5HodoscopeSD(SDname="/hodoscope2");
    12   sdManager->AddNewDetector(hodoscope2);
    13   fHodoscope2Logical->SetSensitiveDetector(hodoscope2);
    14   
    15   auto chamber1 = new B5DriftChamberSD(SDname="/chamber1");
    16   sdManager->AddNewDetector(chamber1);
    17   fWirePlane1Logical->SetSensitiveDetector(chamber1);
    18 
    19   auto chamber2 = new B5DriftChamberSD(SDname="/chamber2");
    20   sdManager->AddNewDetector(chamber2);
    21   fWirePlane2Logical->SetSensitiveDetector(chamber2);
    22   
    23   auto emCalorimeter = new B5EmCalorimeterSD(SDname="/EMcalorimeter");
    24   sdManager->AddNewDetector(emCalorimeter);
    25   fCellLogical->SetSensitiveDetector(emCalorimeter);
    26   
    27   auto hadCalorimeter = new B5HadCalorimeterSD(SDname="/HadCalorimeter");
    28   sdManager->AddNewDetector(hadCalorimeter);
    29   fHadCalScintiLogical->SetSensitiveDetector(hadCalorimeter);
    30 
    31   // magnetic field ----------------------------------------------------------
    32   fMagneticField = new B5MagneticField();
    33   fFieldMgr = new G4FieldManager();
    34   fFieldMgr->SetDetectorField(fMagneticField);
    35   fFieldMgr->CreateChordFinder(fMagneticField);
    36   G4bool forceToAllDaughters = true;
    37   fMagneticLogical->SetFieldManager(fFieldMgr, forceToAllDaughters);
    38 
    39   // Register the field and its manager for deleting
    40   G4AutoDelete::Register(fMagneticField);
    41   G4AutoDelete::Register(fFieldMgr);
    42 }    
    43 
    44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    • 注意到,在这里初始化各个灵敏探测器时,没有设置其对应的 HitCollectionName,这是因为在对应的灵敏探测器类中,已经设置了该名称。
      1 B5EmCalorimeterSD::B5EmCalorimeterSD(G4String name)
      2 : G4VSensitiveDetector(name), 
      3   fHitsCollection(nullptr), fHCID(-1)
      4 {
      5   collectionName.insert("EMcalorimeterColl");
      6 }
     1 #ifndef B5EventAction_h
     2 #define B5EventAction_h 1
     3 
     4 
     5 #include "G4UserEventAction.hh"
     6 #include "globals.hh"
     7 
     8 #include <vector>
     9 
    10 /// Event action
    11 
    12 class B5EventAction : public G4UserEventAction
    13 {
    14 public:
    15     B5EventAction();
    16     virtual ~B5EventAction();
    17     
    18     virtual void BeginOfEventAction(const G4Event*);
    19     virtual void EndOfEventAction(const G4Event*);
    20 
    21     std::vector<G4double>& GetEmCalEdep() { return fEmCalEdep; }
    22     std::vector<G4double>& GetHadCalEdep() { return fEmCalEdep; }
    23     
    24 private:
    25     G4int fHodHC1ID;
    26     G4int fHodHC2ID;
    27     G4int fDriftHC1ID;
    28     G4int fDriftHC2ID;
    29     G4int fEmCalHCID;
    30     G4int fHadCalHCID;
    31     std::vector<G4double> fEmCalEdep;
    32     std::vector<G4double> fHadCalEdep;
    33 };
    34 
    35 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    36 
    37 #endif
      1 #include "B5EventAction.hh"
      2 #include "B5HodoscopeHit.hh"
      3 #include "B5DriftChamberHit.hh"
      4 #include "B5EmCalorimeterHit.hh"
      5 #include "B5HadCalorimeterHit.hh"
      6 #include "B5Constants.hh"
      7 #include "B5Analysis.hh"
      8 
      9 #include "G4Event.hh"
     10 #include "G4RunManager.hh"
     11 #include "G4EventManager.hh"
     12 #include "G4HCofThisEvent.hh"
     13 #include "G4VHitsCollection.hh"
     14 #include "G4SDManager.hh"
     15 #include "G4SystemOfUnits.hh"
     16 #include "G4ios.hh"
     17 
     18 
     19 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     20 
     21 B5EventAction::B5EventAction()
     22 : G4UserEventAction(), 
     23   fHodHC1ID(-1),
     24   fHodHC2ID(-1),
     25   fDriftHC1ID(-1),
     26   fDriftHC2ID(-1),
     27   fEmCalHCID(-1),
     28   fHadCalHCID(-1),
     29   fEmCalEdep(kNofEmCells, 0.), 
     30   fHadCalEdep(kNofHadCells, 0.)
     31 {
     32   // set printing per each event
     33   G4RunManager::GetRunManager()->SetPrintProgress(1);
     34 }
     35 
     36 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     37 
     38 B5EventAction::~B5EventAction()
     39 {}
     40 
     41 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     42 
     43 void B5EventAction::BeginOfEventAction(const G4Event*)
     44 {
     45   if (fHodHC1ID==-1) {
     46     auto sdManager = G4SDManager::GetSDMpointer();
     47     fHodHC1ID = sdManager->GetCollectionID("hodoscope1/hodoscopeColl");
     48     fHodHC2ID = sdManager->GetCollectionID("hodoscope2/hodoscopeColl");
     49     fDriftHC1ID = sdManager->GetCollectionID("chamber1/driftChamberColl");
     50     fDriftHC2ID = sdManager->GetCollectionID("chamber2/driftChamberColl");
     51     fEmCalHCID = sdManager->GetCollectionID("EMcalorimeter/EMcalorimeterColl");
     52     fHadCalHCID = sdManager->GetCollectionID("HadCalorimeter/HadCalorimeterColl");
     53   }
     54 }     
     55 
     56 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
     57 
     58 void B5EventAction::EndOfEventAction(const G4Event* event)
     59 {
     60   auto hce = event->GetHCofThisEvent();
     61   if (!hce) {
     62       G4ExceptionDescription msg;
     63       msg << "No hits collection of this event found." << G4endl; 
     64       G4Exception("B5EventAction::EndOfEventAction()",
     65                   "B5Code001", JustWarning, msg);
     66       return;
     67   }
     68 
     69   // Get hits collections 
     70   auto hHC1 
     71     = static_cast<B5HodoscopeHitsCollection*>(hce->GetHC(fHodHC1ID));
     72     
     73   auto hHC2 
     74     = static_cast<B5HodoscopeHitsCollection*>(hce->GetHC(fHodHC2ID));
     75     
     76   auto dHC1 
     77     = static_cast<B5DriftChamberHitsCollection*>(hce->GetHC(fDriftHC1ID));
     78     
     79   auto dHC2 
     80     = static_cast<B5DriftChamberHitsCollection*>(hce->GetHC(fDriftHC2ID));
     81     
     82   auto ecHC 
     83     = static_cast<B5EmCalorimeterHitsCollection*>(hce->GetHC(fEmCalHCID));
     84     
     85   auto hcHC 
     86     = static_cast<B5HadCalorimeterHitsCollection*>(hce->GetHC(fHadCalHCID));
     87     
     88   if ( (!hHC1) || (!hHC2) || (!dHC1) || (!dHC2) || (!ecHC) || (!hcHC) ) {
     89       G4ExceptionDescription msg;
     90       msg << "Some of hits collections of this event not found." << G4endl; 
     91       G4Exception("B5EventAction::EndOfEventAction()",
     92                   "B5Code001", JustWarning, msg);
     93       return;
     94   }   
     95   
     96   //
     97   // Fill histograms & ntuple
     98   // 
     99   
    100   // Get analysis manager
    101   auto analysisManager = G4AnalysisManager::Instance();
    102  
    103   // Fill histograms
    104  
    105   auto nhit  = dHC1->entries();
    106   analysisManager->FillH1(0, nhit );
    107 
    108   for (auto i=0;i<nhit ;i++) {
    109     auto hit = (*dHC1)[i];
    110     auto localPos = hit->GetLocalPos();
    111     analysisManager->FillH2(0, localPos.x(), localPos.y());
    112   }
    113  
    114   nhit  = dHC2->entries();
    115   analysisManager->FillH1(1, nhit );
    116 
    117   for (auto i=0;i<nhit ;i++) {
    118     auto hit = (*dHC2)[i];
    119     auto localPos = hit->GetLocalPos();
    120     analysisManager->FillH2(1, localPos.x(), localPos.y());
    121   }
    122       
    123   // Fill ntuple
    124   
    125   // Dc1Hits
    126   analysisManager->FillNtupleIColumn(0, dHC1->entries());
    127   // Dc2Hits
    128   analysisManager->FillNtupleIColumn(1, dHC1->entries());
    129   
    130   // ECEnergy
    131   G4int totalEmHit = 0;
    132   G4double totalEmE = 0.;
    133   for (auto i=0;i<kNofEmCells;i++) {
    134     auto hit = (*ecHC)[i];
    135     auto edep = hit->GetEdep();
    136     if (edep>0.) {
    137       totalEmHit++;
    138       totalEmE += edep;
    139     }
    140     fEmCalEdep[i] = edep;
    141   }
    142   analysisManager->FillNtupleDColumn(2, totalEmE);
    143 
    144   // HCEnergy
    145   G4int totalHadHit = 0;
    146   G4double totalHadE = 0.;
    147   for (auto i=0;i<kNofHadCells;i++) {
    148     auto hit = (*hcHC)[i];
    149     auto edep = hit->GetEdep();
    150     if (edep>0.) {
    151         totalHadHit++;
    152         totalHadE += edep;
    153     }
    154     fHadCalEdep[i] = edep;
    155   }
    156   analysisManager->FillNtupleDColumn(3, totalHadE);
    157 
    158   // Time 1
    159   for (auto i=0;i<hHC1->entries();i++) {
    160     analysisManager->FillNtupleDColumn(4,(*hHC1)[i]->GetTime());
    161   }
    162     
    163   // Time 2
    164   for (auto i=0;i<hHC2->entries();i++) {
    165     analysisManager->FillNtupleDColumn(5,(*hHC2)[i]->GetTime());
    166   }
    167   
    168   analysisManager->AddNtupleRow();  
    169   
    170   //
    171   // Print diagnostics
    172   // 
    173   
    174   auto printModulo = G4RunManager::GetRunManager()->GetPrintProgress();
    175   if ( printModulo==0 || event->GetEventID() % printModulo != 0) return;
    176   
    177   auto primary = event->GetPrimaryVertex(0)->GetPrimary(0);
    178   G4cout 
    179     << G4endl
    180     << ">>> Event " << event->GetEventID() << " >>> Simulation truth : "
    181     << primary->GetG4code()->GetParticleName()
    182     << " " << primary->GetMomentum() << G4endl;
    183   
    184   // Hodoscope 1
    185   nhit  = hHC1->entries();
    186   G4cout << "Hodoscope 1 has " << nhit  << " hits." << G4endl;
    187   for (auto i=0;i<nhit ;i++) {
    188     auto hit = (*hHC1)[i];
    189     hit->Print();
    190   }
    191 
    192   // Hodoscope 2
    193   nhit  = hHC2->entries();
    194   G4cout << "Hodoscope 2 has " << nhit  << " hits." << G4endl;
    195   for (auto i=0;i<nhit ;i++) {
    196     auto hit = (*hHC2)[i];
    197     hit->Print();
    198   }
    199 
    200   // Drift chamber 1
    201   nhit  = dHC1->entries();
    202   G4cout << "Drift Chamber 1 has " << nhit  << " hits." << G4endl;
    203   for (auto layer=0;layer<kNofChambers;layer++) {
    204     for (auto i=0;i<nhit ;i++) {
    205       auto hit = (*dHC1)[i];
    206       if (hit->GetLayerID()==layer) hit->Print();
    207     }
    208   }
    209 
    210   // Drift chamber 2
    211   nhit  = dHC2->entries();
    212   G4cout << "Drift Chamber 2 has " << nhit  << " hits." << G4endl;
    213   for (auto layer=0;layer<kNofChambers;layer++) {
    214     for (auto i=0;i<nhit ;i++) {
    215       auto hit = (*dHC2)[i];
    216       if (hit->GetLayerID()==layer) hit->Print();
    217     }
    218   }
    219 
    220   // EM calorimeter
    221   G4cout << "EM Calorimeter has " << totalEmHit << " hits. Total Edep is "
    222     << totalEmE/MeV << " (MeV)" << G4endl;
    223 
    224   // Had calorimeter
    225   G4cout << "Hadron Calorimeter has " << totalHadHit << " hits. Total Edep is "
    226     << totalHadE/MeV << " (MeV)" << G4endl;
    227 }
    228 
    229 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
    • 第 47 - 52 行,是为了得到不同的灵敏探测器所产生的 hitCollection 在 G4HCofThisEvent 容器中的位置,使用灵敏探测器管理器类的成员函数  GetCollectionID(G4String colName) 返回对应的 hitCollection 的 ID,其参数为 SDname/hitCollectionName,中间需要加"/",入示例中所示。
    • 在  EndOfEventAction() 中,首先需要定义一个  GetHCofThisEvent 容器对象,通过 hitCollectionID 索引得到 hitCollection 的容器,在文档中的第 69 - 94 行。
    • 第 130 - 156 行,这里用了累加,将每一个 hitCollection 容器中 hit 对象的能量相加,得到一个 Event 中,在一个灵敏探测器中沉积的总的能量。
  • 相关阅读:
    JavaScript 弹窗
    创建对象构造器
    DOM事件
    document对象“还在更新”
    JavaScript 闭包
    使用 "use strict" 指令
    constructor 属性
    2019暑期集训第一周小结
    无向图求割边
    矩阵快速幂
  • 原文地址:https://www.cnblogs.com/kurrrr/p/13661959.html
Copyright © 2011-2022 走看看