/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 #include "DsOpStackAction.h" 00002 00003 #include "DetDesc/IPVolume.h" 00004 #include "DetHelpers/ICoordSysSvc.h" 00005 #include "DetDesc/DetectorElement.h" 00006 #include "DetDesc/IGeometryInfo.h" 00007 #include "GaudiKernel/Service.h" 00008 #include "GaudiKernel/DeclareFactoryEntries.h" 00009 00010 #include <G4ClassificationOfNewTrack.hh> 00011 #include <G4SDManager.hh> 00012 #include <G4RunManager.hh> 00013 #include <G4TrackStatus.hh> 00014 #include <G4ParticleDefinition.hh> 00015 #include <G4Event.hh> 00016 #include <G4ParticleTypes.hh> 00017 #include <G4Track.hh> 00018 00019 DECLARE_TOOL_FACTORY(DsOpStackAction); 00020 00021 00022 DsOpStackAction::DsOpStackAction ( const std::string& type , 00023 const std::string& name , 00024 const IInterface* parent ) 00025 : GiGaStackActionBase( type, name, parent ) , 00026 stage(0), 00027 PhotonNumbers(0), 00028 NeutronNumbers(0), 00029 interestingEvt(false), 00030 m_csvc(0) 00031 { 00032 declareProperty("TightCut",m_tightCut = false, " cut to select Neutron only event in the AD."); 00033 declareProperty("PhotonCut",m_photonCut = false, " Kill all the optical photons in the process."); 00034 declareProperty("MaxPhoton",m_maxPhoton = 1e6, " Max number of photons to be hold."); 00035 } 00036 00037 00038 StatusCode DsOpStackAction::initialize() 00039 { 00040 info() << "DsOpStackAction::initialize()" << endreq; 00041 00042 StatusCode sc = GiGaStackActionBase::initialize(); 00043 if (sc.isFailure()) return sc; 00044 00045 00046 if ( service("CoordSysSvc", m_csvc).isFailure()) { 00047 error() << " No CoordSysSvc available." << endreq; 00048 return StatusCode::FAILURE; 00049 } 00050 00051 return StatusCode::SUCCESS; 00052 } 00053 00054 StatusCode DsOpStackAction::finalize() 00055 { 00056 info() << "DsOpStackAction::finalize()" << endreq; 00057 neutronList.clear(); 00058 return GiGaStackActionBase::finalize(); 00059 } 00060 00061 //-------------------------------------------------------------------------- 00062 00063 G4ClassificationOfNewTrack DsOpStackAction::ClassifyNewTrack (const G4Track* aTrack) { 00064 00065 // info() << "DsOpStackAction::ClassifyNewTrack: " << endreq; 00066 00067 G4ClassificationOfNewTrack classification = fUrgent; 00068 //info()<< " ParentID: "<< aTrack->GetParentID()<< " CurrentID: "<<aTrack->GetTrackID()<<endreq; 00069 00070 00071 switch(stage) 00072 { 00073 case 0: // if optical photon is the the secondary particles and below memory threshold, 00074 // put them in waiting. 00075 00076 // tightcut selection here. 00077 if(aTrack->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition()){ 00078 if(m_tightCut){ 00079 if( aTrack->GetDefinition()==G4Neutron::NeutronDefinition()) 00080 { 00081 info()<<" It is a neutron event! " <<endreq; 00082 NeutronNumbers++; 00083 neutronList.push_back(aTrack->GetTrackID()); //save neutron's trackID for later use. 00084 break; 00085 } 00086 00087 00088 if( aTrack->GetDefinition()==G4Gamma::GammaDefinition() 00089 && (aTrack->GetTrackID()-aTrack->GetParentID())==1) //only if the gamma has a direct parent. 00090 { 00091 if(!interestingEvt){ 00092 interestingEvt=this->IsAInterestingTrack(aTrack); 00093 //info()<< "Particle: "<<aTrack->GetDefinition()->GetParticleName() <<endreq; 00094 } 00095 break; 00096 } 00097 } 00098 else { 00099 if( aTrack->GetDefinition()==G4Neutron::NeutronDefinition()) 00100 { 00101 NeutronNumbers++; 00102 break; 00103 } 00104 if (aTrack->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition()) { 00105 if(!interestingEvt){ 00106 interestingEvt=this->PossibleInterestingTrack(aTrack); 00107 } 00108 break; 00109 } 00110 } 00111 } 00112 else{ 00113 00114 PhotonNumbers++; 00115 00116 00117 // ------unother way of doing this is to use the processname to select events-- 00118 // if(aTrack->GetCreatorProcess()){ 00119 // G4String ProcessName=aTrack->GetCreatorProcess()->GetProcessName(); 00120 // info()<< " Proccess Name: "<< ProcessName<<endreq; 00121 // } 00122 00123 00125 if (m_photonCut) { 00126 classification=fKill; 00127 break; 00128 } 00129 else if(aTrack->GetParentID()>0 && PhotonNumbers<=m_maxPhoton && !interestingEvt) 00130 { 00131 //if too many optical photons been generated and too many optical photons hold 00132 //in the stack, may cause 'out of memory' problem 00133 00134 // only hold optical photon if it is secondary 00135 00136 // G4ThreeVector position = aTrack->GetPosition(); 00137 // G4ThreeVector direction = aTrack->GetMomentumDirection(); 00138 // G4ThreeVector polarization = aTrack->GetPolarization(); 00139 // G4double energy = aTrack->GetKineticEnergy(); 00140 // G4double time = aTrack->GetGlobalTime(); 00141 // info()<< " Position " << position.x()<< " time: " <<time<<endreq; 00142 classification=fWaiting; 00143 break; 00144 } 00145 } 00146 00147 classification = fUrgent; 00148 break; 00149 00150 case 1: 00151 // info()<<" In Stage 1, propogating all the stacked optical photons! "<<endreq; 00152 classification = fUrgent; 00153 break; 00154 00155 default: 00156 classification = fUrgent; 00157 } 00158 return classification; 00159 } 00160 00161 //------------------------------------------------------------------------- 00162 //-------------throw away non-interesting events, and----------------------- 00163 //------------propogate optical photons otherwise ------------------ 00164 //------------------------------------------------------------------- 00165 00166 void DsOpStackAction::NewStage() 00167 { 00168 00169 info()<< " StackingAction::NewStage! "<<endreq; 00170 info()<< " Number of Optical Photons generated: "<< PhotonNumbers<<endreq; 00171 info()<< " Number of Neutron generated: "<< NeutronNumbers<<endreq; 00172 00173 if(m_tightCut){ 00174 info() << "Tight Cut selected: only select AD gamma events from neutrons! " <<endreq; 00175 } 00176 else{ 00177 info() << " select Events with any new particles generated in the AD! " <<endreq; 00178 } 00179 00180 if(PhotonNumbers>m_maxPhoton) { 00181 info() << " Get an event with Large number of Photons! " <<endreq; 00182 } 00183 00184 if(m_photonCut){ 00185 info() << " All the Optical Photons killed in this event! " <<endreq; 00186 } 00187 00188 stage++; 00189 00190 if(interestingEvt) 00191 { 00192 info()<<" An interesting event! Let's go on!"<<endreq; 00193 stackManager->ReClassify(); 00194 } 00195 else { 00196 info()<< "Boring event, aborting..."<<endreq; 00197 stackManager->clear(); //abort the event 00198 } 00199 } 00200 00201 00202 //----------------------Reset ----------------------------------- 00203 void DsOpStackAction::PrepareNewEvent() 00204 { 00205 info()<< " StackingAction::PrepareNewEvent! "<<endreq; 00206 interestingEvt=false; 00207 stage=0; 00208 PhotonNumbers=0; 00209 NeutronNumbers=0; 00210 neutronList.clear(); 00211 } 00212 00213 //-----------------If the Gamma neutron's daughter ? --------------------- 00214 00215 G4bool DsOpStackAction::IsNeutronDaughter(const G4int id, const vector<G4int> aList) 00216 { 00217 00218 //check if the gamma is the daughter of neutrons. 00219 G4bool isDaughter(false); 00220 for(size_t ii=0;ii<aList.size();ii++){ 00221 if(aList[ii]==id || aList[ii]==id-1) { 00222 info()<<" neutron TrackID: "<<aList[ii]<< " been Captured! "<< endreq; 00223 isDaughter=true; 00224 break; 00225 } 00226 } 00227 return isDaughter; 00228 }; 00229 00230 // ------------- If the neutron been captured in the AD ? ------------------- 00231 00232 G4bool DsOpStackAction::IsAInterestingTrack(const G4Track* aTrack) 00233 { 00234 00235 // info()<< " Am I an interesting event???" <<endreq; 00236 00237 G4int trkID=aTrack->GetParentID(); //get Gamma's parentID 00238 00239 IDetectorElement *de; 00240 Gaudi::XYZPoint gp(aTrack->GetPosition().x(),aTrack->GetPosition().y(),aTrack->GetPosition().z()); 00241 00242 //Get DetectorElement from the global postion. 00243 de = m_csvc->coordSysDE(gp); 00244 if(!de){ 00245 debug()<<" Particle Name: "<<aTrack->GetDefinition()->GetParticleName()<< " at position: "<<gp 00246 <<" with Process Name: "<<aTrack->GetCreatorProcess()->GetProcessName()<<endreq; 00247 } 00248 00249 //Ignore the track outside of our global volumes. 00250 if(de){ 00251 IGeometryInfo *ginfo=de->geometry(); 00252 if(ginfo){ 00253 if( IsNeutronDaughter(trkID, neutronList)) 00254 //if Gamma's parent is neutron, check if they are in the AD. 00255 { 00256 // G4String ProcessName=aTrack->GetCreatorProcess()->GetProcessName(); 00257 const ILVolume *lv=ginfo->lvolume(); 00258 if(lv){ 00259 G4String MaterialName = lv->materialName(); 00260 00261 // info() << " materialName: "<< MaterialName <<endreq; 00262 00263 if( MaterialName=="/dd/Materials/MineralOil" 00264 || MaterialName== "/dd/Materials/GdDopedLS" 00265 || MaterialName== "/dd/Materials/LiquidScintillator" 00266 || MaterialName== "/dd/Materials/Acrylic") { 00267 00268 info()<< "Find a Interesting Event in %s !!!" << MaterialName<<endreq; 00269 return true; 00270 } 00271 } 00272 } 00273 } 00274 } 00275 return false; 00276 } 00277 00278 00279 // ------------- If any new particles generated in the AD -------------------- 00280 00281 G4bool DsOpStackAction::PossibleInterestingTrack(const G4Track* aTrack) 00282 { 00283 00284 //info()<< " Am I an possible interesting event???" <<endreq; 00285 00286 IDetectorElement *de; 00287 Gaudi::XYZPoint gp(aTrack->GetPosition().x(),aTrack->GetPosition().y(),aTrack->GetPosition().z()); 00288 00289 //Get DetectorElement from the global postion. 00290 de = m_csvc->coordSysDE(gp); 00291 00292 // If the new particle generated inside of the AD, accept it 00293 if(de){ 00294 IGeometryInfo *ginfo=de->geometry(); 00295 if(ginfo){ 00296 { 00297 const ILVolume *lv=ginfo->lvolume(); 00298 if(lv){ 00299 G4String MaterialName = lv->materialName(); 00300 00301 if( MaterialName=="/dd/Materials/MineralOil" 00302 || MaterialName== "/dd/Materials/GdDopedLS" 00303 || MaterialName== "/dd/Materials/LiquidScintillator" 00304 || MaterialName== "/dd/Materials/Acrylic") { 00305 00306 info()<< "Find a good Event in AD in "<< MaterialName<< " !! "<< endreq; 00307 return true; 00308 } 00309 } 00310 } 00311 } 00312 } 00313 return false; 00314 } 00315 00316 00317 00318 //-----------------------END----------------------------------