File indexing completed on 2026-09-21 08:29:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "ExN04StackingAction.hh"
0030
0031 #include "ExN04StackingActionMessenger.hh"
0032
0033 #include "G4Event.hh"
0034 #include "G4HCofThisEvent.hh"
0035 #include "G4ParticleDefinition.hh"
0036 #include "G4ParticleTypes.hh"
0037 #include "G4RunManager.hh"
0038 #include "G4SDManager.hh"
0039 #include "G4SystemOfUnits.hh"
0040 #include "G4Track.hh"
0041 #include "G4TrackStatus.hh"
0042
0043
0044 ExN04StackingAction::ExN04StackingAction()
0045 : G4UserStackingAction(), fTrkHits(0), fMuonHits(0), fStage(0)
0046 {
0047 fAngRoI = 30.0 * deg;
0048 fReqMuon = 2;
0049 fReqIso = 10;
0050 fMessenger = new ExN04StackingActionMessenger(this);
0051 }
0052
0053
0054 ExN04StackingAction::~ExN04StackingAction()
0055 {
0056 delete fMessenger;
0057 }
0058
0059
0060 G4ClassificationOfNewTrack ExN04StackingAction::ClassifyNewTrack(const G4Track* aTrack)
0061 {
0062 G4ClassificationOfNewTrack classification = fWaiting;
0063 switch (fStage) {
0064 case 0:
0065 if (aTrack->GetParentID() == 0) {
0066 G4ParticleDefinition* particleType = aTrack->GetDefinition();
0067 if ((particleType == G4MuonPlus::MuonPlusDefinition())
0068 || (particleType == G4MuonMinus::MuonMinusDefinition()))
0069 {
0070 classification = fUrgent;
0071 }
0072 }
0073 break;
0074
0075 case 1:
0076
0077 if (aTrack->GetParentID() != 0) {
0078 break;
0079 }
0080 if (aTrack->GetTrackStatus() == fSuspend) {
0081 break;
0082 }
0083 if (aTrack->GetDefinition()->GetPDGCharge() == 0.) {
0084 break;
0085 }
0086 classification = fUrgent;
0087 break;
0088
0089 default:
0090
0091
0092 if (aTrack->GetParentID() == 0) {
0093 classification = fUrgent;
0094 break;
0095 }
0096 if ((fAngRoI < 0.) || InsideRoI(aTrack, fAngRoI)) {
0097 classification = fUrgent;
0098 break;
0099 }
0100 classification = fKill;
0101 }
0102 return classification;
0103 }
0104
0105
0106 G4bool ExN04StackingAction::InsideRoI(const G4Track* aTrack, G4double ang)
0107 {
0108 if (!fMuonHits) {
0109 fMuonHits = (ExN04MuonHitsCollection*)GetCollection("muonCollection");
0110 }
0111 if (!fMuonHits) {
0112 G4cerr << "muonCollection NOT FOUND" << G4endl;
0113 return true;
0114 }
0115
0116 G4int nhits = fMuonHits->entries();
0117
0118 const G4ThreeVector trPos = aTrack->GetPosition();
0119 for (G4int i = 0; i < nhits; i++) {
0120 G4ThreeVector muHitPos = (*fMuonHits)[i]->GetPos();
0121 G4double angl = muHitPos.angle(trPos);
0122 if (angl < ang) {
0123 return true;
0124 }
0125 }
0126
0127 return false;
0128 }
0129
0130
0131 G4VHitsCollection* ExN04StackingAction::GetCollection(G4String colName)
0132 {
0133 G4SDManager* SDMan = G4SDManager::GetSDMpointer();
0134 G4RunManager* runMan = G4RunManager::GetRunManager();
0135 int colID = SDMan->GetCollectionID(colName);
0136 if (colID >= 0) {
0137 const G4Event* currentEvent = runMan->GetCurrentEvent();
0138 G4HCofThisEvent* HCE = currentEvent->GetHCofThisEvent();
0139 return HCE->GetHC(colID);
0140 }
0141 return 0;
0142 }
0143
0144
0145 void ExN04StackingAction::NewStage()
0146 {
0147 fStage++;
0148 G4int nhits;
0149 if (fStage == 1) {
0150
0151
0152 if (!fMuonHits) {
0153 fMuonHits = (ExN04MuonHitsCollection*)GetCollection("muonCollection");
0154 }
0155 if (!fMuonHits) {
0156 G4cerr << "muonCollection NOT FOUND" << G4endl;
0157 return;
0158 }
0159 nhits = fMuonHits->entries();
0160 G4cout << "Stage 0->1 : " << nhits << " hits found in the muon chamber." << G4endl;
0161 if (nhits < fReqMuon) {
0162 stackManager->clear();
0163 G4cout << "++++++++ event aborted" << G4endl;
0164 return;
0165 }
0166 stackManager->ReClassify();
0167 return;
0168 }
0169
0170 else if (fStage == 2) {
0171
0172
0173
0174
0175
0176
0177 nhits = fMuonHits->entries();
0178 if (!fTrkHits) {
0179 fTrkHits = (ExN04TrackerHitsCollection*)GetCollection("trackerCollection");
0180 }
0181 if (!fTrkHits) {
0182 G4cerr << "trackerCollection NOT FOUND" << G4endl;
0183 return;
0184 }
0185 G4int nTrkhits = fTrkHits->entries();
0186 G4int isoMuon = 0;
0187 for (G4int j = 0; j < nhits; j++) {
0188 G4ThreeVector hitPos = (*fMuonHits)[j]->GetPos();
0189 G4int nhitIn = 0;
0190 for (G4int jj = 0; (jj < nTrkhits) && (nhitIn <= fReqIso); jj++) {
0191 G4ThreeVector trkhitPos = (*fTrkHits)[jj]->GetPos();
0192 if (trkhitPos.angle(hitPos) < fAngRoI) nhitIn++;
0193 }
0194 if (nhitIn <= fReqIso) isoMuon++;
0195 }
0196 G4cout << "Stage 1->2 : " << isoMuon << " isolated muon found." << G4endl;
0197 if (isoMuon < fReqIsoMuon) {
0198 stackManager->clear();
0199 G4cout << "++++++++ event aborted" << G4endl;
0200 return;
0201 }
0202 stackManager->ReClassify();
0203 return;
0204 }
0205
0206 else {
0207
0208 stackManager->ReClassify();
0209 }
0210 }
0211
0212
0213 void ExN04StackingAction::PrepareNewEvent()
0214 {
0215 fStage = 0;
0216 fTrkHits = 0;
0217 fMuonHits = 0;
0218 }