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
00066
00067 G4ClassificationOfNewTrack classification = fUrgent;
00068
00069
00070
00071 switch(stage)
00072 {
00073 case 0:
00074
00075
00076
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());
00084 break;
00085 }
00086
00087
00088 if( aTrack->GetDefinition()==G4Gamma::GammaDefinition()
00089 && (aTrack->GetTrackID()-aTrack->GetParentID())==1)
00090 {
00091 if(!interestingEvt){
00092 interestingEvt=this->IsAInterestingTrack(aTrack);
00093
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
00118
00119
00120
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
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 classification=fWaiting;
00143 break;
00144 }
00145 }
00146
00147 classification = fUrgent;
00148 break;
00149
00150 case 1:
00151
00152 classification = fUrgent;
00153 break;
00154
00155 default:
00156 classification = fUrgent;
00157 }
00158 return classification;
00159 }
00160
00161
00162
00163
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();
00198 }
00199 }
00200
00201
00202
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
00214
00215 G4bool DsOpStackAction::IsNeutronDaughter(const G4int id, const vector<G4int> aList)
00216 {
00217
00218
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
00231
00232 G4bool DsOpStackAction::IsAInterestingTrack(const G4Track* aTrack)
00233 {
00234
00235
00236
00237 G4int trkID=aTrack->GetParentID();
00238
00239 IDetectorElement *de;
00240 Gaudi::XYZPoint gp(aTrack->GetPosition().x(),aTrack->GetPosition().y(),aTrack->GetPosition().z());
00241
00242
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
00250 if(de){
00251 IGeometryInfo *ginfo=de->geometry();
00252 if(ginfo){
00253 if( IsNeutronDaughter(trkID, neutronList))
00254
00255 {
00256
00257 const ILVolume *lv=ginfo->lvolume();
00258 if(lv){
00259 G4String MaterialName = lv->materialName();
00260
00261
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
00280
00281 G4bool DsOpStackAction::PossibleInterestingTrack(const G4Track* aTrack)
00282 {
00283
00284
00285
00286 IDetectorElement *de;
00287 Gaudi::XYZPoint gp(aTrack->GetPosition().x(),aTrack->GetPosition().y(),aTrack->GetPosition().z());
00288
00289
00290 de = m_csvc->coordSysDE(gp);
00291
00292
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