00001 #include "SimG4Core/Application/interface/StackingAction.h"
00002 #include "SimG4Core/Notification/interface/CurrentG4Track.h"
00003 #include "SimG4Core/Notification/interface/NewTrackAction.h"
00004 #include "SimG4Core/Notification/interface/TrackInformation.h"
00005 #include "SimG4Core/Notification/interface/TrackInformationExtractor.h"
00006
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008
00009 #include "G4VProcess.hh"
00010 #include "G4PhysicalVolumeStore.hh"
00011
00012 StackingAction::StackingAction(const edm::ParameterSet & p): tracker(0),
00013 calo(0), muon(0) {
00014 trackNeutrino = p.getParameter<bool>("TrackNeutrino");
00015 killHeavy = p.getParameter<bool>("KillHeavy");
00016 kmaxIon = p.getParameter<double>("IonThreshold")*MeV;
00017 kmaxProton = p.getParameter<double>("ProtonThreshold")*MeV;
00018 kmaxNeutron = p.getParameter<double>("NeutronThreshold")*MeV;
00019 savePDandCinTracker = p.getUntrackedParameter<bool>("SavePrimaryDecayProductsAndConversionsInTracker",false);
00020 savePDandCinCalo = p.getUntrackedParameter<bool>("SavePrimaryDecayProductsAndConversionsInCalo",false);
00021 savePDandCinMuon = p.getUntrackedParameter<bool>("SavePrimaryDecayProductsAndConversionsInMuon",false);
00022 saveFirstSecondary = p.getUntrackedParameter<bool>("SaveFirstLevelSecondary",false);
00023
00024 edm::LogInfo("SimG4CoreApplication") << "StackingAction initiated with"
00025 << " flag for saving decay products in "
00026 << " Tracker: " << savePDandCinTracker
00027 << " in Calo: " << savePDandCinCalo
00028 << " in Muon: " << savePDandCinMuon
00029 << "\n saveFirstSecondary"
00030 << ": " << saveFirstSecondary
00031 << " Flag for tracking neutrino: "
00032 << trackNeutrino << " Killing Flag "
00033 << killHeavy << " protons below "
00034 << kmaxProton <<" MeV, neutrons below "
00035 << kmaxNeutron << " MeV and ions"
00036 << " below " << kmaxIon << " MeV\n";
00037
00038 initPointer();
00039 }
00040
00041 StackingAction::~StackingAction() {}
00042
00043 G4ClassificationOfNewTrack StackingAction::ClassifyNewTrack(const G4Track * aTrack) {
00044
00045
00046 G4ClassificationOfNewTrack classification = fUrgent;
00047 int flag = 0;
00048
00049 NewTrackAction newTA;
00050 if (aTrack->GetCreatorProcess()==0 || aTrack->GetParentID()==0)
00051 newTA.primary(aTrack);
00052 else {
00053 const G4Track * mother = CurrentG4Track::track();
00054 if ((savePDandCinTracker && isThisVolume(aTrack->GetTouchable(),tracker))||
00055 (savePDandCinCalo && isThisVolume(aTrack->GetTouchable(),calo)) ||
00056 (savePDandCinMuon && isThisVolume(aTrack->GetTouchable(),muon)))
00057 flag = isItPrimaryDecayProductOrConversion(aTrack, *mother);
00058 if (saveFirstSecondary) flag = isItFromPrimary(*mother, flag);
00059 newTA.secondary(aTrack, *mother, flag);
00060 if (killHeavy) {
00061 int pdg = aTrack->GetDefinition()->GetPDGEncoding();
00062 double ke = aTrack->GetKineticEnergy()/MeV;
00063 if (((pdg/1000000000 == 1) && (((pdg/10000)%100) > 0) &&
00064 (((pdg/10)%100) > 0) && (ke<kmaxIon)) ||
00065 ((pdg == 2212) && (ke < kmaxProton)) ||
00066 ((pdg == 2112) && (ke < kmaxNeutron))) classification = fKill;
00067 }
00068 if (!trackNeutrino) {
00069 int pdg = std::abs(aTrack->GetDefinition()->GetPDGEncoding());
00070 if (pdg == 12 || pdg == 14 || pdg == 16 || pdg == 18)
00071 classification = fKill;
00072 }
00073 LogDebug("SimG4CoreApplication") << "StackingAction:Classify Track "
00074 << aTrack->GetTrackID() << " Parent "
00075 << aTrack->GetParentID() << " Type "
00076 << aTrack->GetDefinition()->GetParticleName()
00077 << " K.E. " << aTrack->GetKineticEnergy()/MeV
00078 << " MeV as " << classification
00079 << " Flag " << flag;
00080 }
00081 return classification;
00082 }
00083
00084 void StackingAction::NewStage() {}
00085
00086 void StackingAction::PrepareNewEvent() {}
00087
00088 void StackingAction::initPointer() {
00089
00090 const G4PhysicalVolumeStore * pvs = G4PhysicalVolumeStore::GetInstance();
00091 if (pvs) {
00092 std::vector<G4VPhysicalVolume*>::const_iterator pvcite;
00093 for (pvcite = pvs->begin(); pvcite != pvs->end(); pvcite++) {
00094 if (savePDandCinTracker) {
00095 if ((*pvcite)->GetName() == "Tracker") tracker = (*pvcite);
00096 }
00097 if (savePDandCinCalo) {
00098 if ((*pvcite)->GetName() == "CALO") calo = (*pvcite);
00099 }
00100 if (savePDandCinMuon) {
00101 if ((*pvcite)->GetName() == "MUON") muon = (*pvcite);
00102 }
00103 if ( (!savePDandCinTracker || tracker) && (!savePDandCinCalo || calo) &&
00104 (!savePDandCinMuon || muon ) ) break;
00105 }
00106 edm::LogInfo("SimG4CoreApplication") << "Pointers for Tracker " << tracker
00107 << ", Calo " << calo << ", Muon "
00108 << muon;
00109 if (tracker) edm::LogInfo("SimG4CoreApplication") << "Tracker vol name "
00110 << tracker->GetName();
00111 if (calo) edm::LogInfo("SimG4CoreApplication")<< "Calorimeter vol name "
00112 << calo->GetName();
00113 if (muon) edm::LogInfo("SimG4CoreApplication") << "Muon vol name "
00114 << muon->GetName();
00115 }
00116 }
00117
00118 bool StackingAction::isThisVolume(const G4VTouchable* touch,
00119 G4VPhysicalVolume* pv) const {
00120
00121 int level = ((touch->GetHistoryDepth())+1);
00122 if (level >= 3) {
00123 int ii = level - 3;
00124 bool flag = (touch->GetVolume(ii) == pv);
00125 return flag;
00126 }
00127 return false;
00128 }
00129
00130 int StackingAction::isItPrimaryDecayProductOrConversion(const G4Track * aTrack,
00131 const G4Track & mother) const {
00132
00133 int flag = 0;
00134 TrackInformationExtractor extractor;
00135 const TrackInformation & motherInfo(extractor(mother));
00136
00137 if (motherInfo.isPrimary()) {
00138 if (aTrack->GetCreatorProcess()->GetProcessType() == fDecay &&
00139 aTrack->GetCreatorProcess()->GetProcessName() == "Decay") flag = 1;
00140 else if (aTrack->GetCreatorProcess()->GetProcessType() == fElectromagnetic &&
00141 aTrack->GetCreatorProcess()->GetProcessName() == "conv") flag = 2;
00142 }
00143 return flag;
00144 }
00145
00146 int StackingAction::isItFromPrimary(const G4Track & mother, int flagIn) const {
00147
00148 int flag = flagIn;
00149 if (flag != 1) {
00150 TrackInformationExtractor extractor;
00151 const TrackInformation & motherInfo(extractor(mother));
00152 if (motherInfo.isPrimary()) flag = 3;
00153 }
00154 return flag;
00155 }