00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "DsFastMuonStackAction.h"
00016
00017 #include "DetDesc/IPVolume.h"
00018 #include "DetHelpers/ICoordSysSvc.h"
00019 #include "DetDesc/DetectorElement.h"
00020 #include "DetDesc/IGeometryInfo.h"
00021 #include "GaudiKernel/Service.h"
00022 #include "GaudiKernel/DeclareFactoryEntries.h"
00023 #include "GaudiKernel/IRndmGenSvc.h"
00024
00025 #include <G4SDManager.hh>
00026 #include <G4RunManager.hh>
00027 #include <G4TrackStatus.hh>
00028 #include <G4ThreeVector.hh>
00029 #include <G4ParticleDefinition.hh>
00030 #include <G4Event.hh>
00031 #include <G4String.hh>
00032 #include <G4ParticleTypes.hh>
00033 #include <G4VTouchable.hh>
00034 #include <G4Track.hh>
00035 #include <G4ClassificationOfNewTrack.hh>
00036
00037 #ifdef DSFMSA_DEBUGPOSITION
00038 #include <TFile.h>
00039 #include <TTree.h>
00040 #endif
00041
00042 DECLARE_TOOL_FACTORY(DsFastMuonStackAction);
00043
00044 DsFastMuonStackAction::DsFastMuonStackAction ( const std::string& type ,
00045 const std::string& name ,
00046 const IInterface* parent )
00047 : GiGaStackActionBase( type, name, parent )
00048 , m_csvc(0)
00049 , fTrackRemainingPhotons(false)
00050 {
00051 declareProperty("Detectors", m_detectors, "A list with detector elements you are interested in.");
00052 declareProperty("Limits", m_limits, "A list with maximal number of photons to start weighting "
00053 "for each detector element respectively.");
00054 declareProperty("Weights", m_weights, "A list with photon weights for each detector respectively.");
00055 }
00056
00057 StatusCode DsFastMuonStackAction::initialize()
00058 {
00059 if ( m_detectors.size()!=m_limits.size() || m_limits.size()!=m_weights.size() ){
00060 error() << "Specified parameter lists are inconsistent. Check sizes." << endreq;
00061 return StatusCode::FAILURE;
00062 }
00063 for (unsigned int i(0); i<m_detectors.size(); i++){
00064 IDetectorElement* de=getDet<IDetectorElement>(m_detectors[i]);;
00065 if ( !de ) {
00066 error() << "Detector '"<<m_detectors[i] <<"' not found." << endreq;
00067 return StatusCode::FAILURE;
00068 }
00069 #ifdef DSFMSA_DEBUGPOSITION
00070 tmpMap[de]=int(i)+1;
00071 #endif
00072 fCounter[de]=DECounter(m_limits[i], m_weights[i]);
00073 int size=m_limits[i]*sizeof(G4Track)/1024.;
00074 info()<<"Entry "<<i<<": photons are weighted with w="<<m_weights[i]
00075 <<", after N="<<m_limits[i]
00076 <<" (up to "<<size<<" KB) in detector element:"<<endreq;
00077 info() << m_detectors[i] << endreq;
00078 }
00079
00080 if ( fCounter.empty() ) {
00081 error() << "Got no detector elements to look after" << endreq;
00082 return StatusCode::FAILURE;
00083 }
00084
00085 StatusCode sc = GiGaStackActionBase::initialize();
00086 if (sc.isFailure()) return sc;
00087
00088 if ( service("CoordSysSvc", m_csvc).isFailure()) {
00089 error() << " No CoordSysSvc available." << endreq;
00090 return StatusCode::FAILURE;
00091 }
00092
00093
00094 IRndmGenSvc *rgs = 0;
00095 if (service("RndmGenSvc",rgs,true).isFailure()) {
00096 fatal() << "Failed to get random service" << endreq;
00097 return StatusCode::FAILURE;
00098 }
00099 sc = m_uni.initialize(rgs, Rndm::Flat(0,1));
00100 if (sc.isFailure()) {
00101 fatal() << "Failed to initialize uniform random numbers" << endreq;
00102 return StatusCode::FAILURE;
00103 }
00104
00105 #ifdef DSFMSA_DEBUGPOSITION
00106 G4cerr<<"create file"<<G4endl;
00107 event=0;
00108 file = new TFile("testCoord.root", "RECREATE");
00109 tree = new TTree("coordtree", "coordinates tree");
00110 tree->Branch("x", &xx, "x/D");
00111 tree->Branch("y", &yy, "y/D");
00112 tree->Branch("z", &zz, "z/D");
00113 tree->Branch("i", &ii, "i/I");
00114 tree->Branch("e", &event, "e/I");
00115 #endif
00116
00117 return StatusCode::SUCCESS;
00118 }
00119
00120 StatusCode DsFastMuonStackAction::finalize()
00121 {
00122 #ifdef DSFMSA_DEBUGPOSITION
00123 file->Write();
00124 file->Close();
00125 #endif
00126 return GiGaStackActionBase::finalize();
00127 }
00128
00129 G4ClassificationOfNewTrack DsFastMuonStackAction::ClassifyNewTrack (const G4Track* aTrack) {
00130
00131
00132
00133 if (aTrack->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition()) return fUrgent;
00134
00135
00136
00137
00138
00139 IDetectorElement* de;
00140 const G4VTouchable* touchable=aTrack->GetTouchable();
00141 std::map<const G4VTouchable*, IDetectorElement*>::iterator cacheIt=fTouchablesCache.find(touchable);
00142 std::map<IDetectorElement*, DECounter>::iterator it, end=fCounter.end();
00143 if ( cacheIt==fTouchablesCache.end() ) {
00144
00145
00146
00147
00148
00149 Gaudi::XYZPoint position(aTrack->GetPosition().x(),aTrack->GetPosition().y(),aTrack->GetPosition().z());
00150 IDetectorElement* de=m_csvc->belongsToDE(position);
00151 it=fCounter.find(de);
00152 while ( it==end && de ){
00153
00154
00155
00156 de=de->parentIDetectorElement();
00157 it=fCounter.find(de);
00158 }
00159
00160 if ( touchable ) fTouchablesCache[touchable]=de;
00161 else {
00162
00163
00164
00165 return fUrgent;
00166 }
00167 if ( !de ) {
00168 return fUrgent;
00169 }
00170 }
00171 else {
00172
00173
00174 de=cacheIt->second;
00175 if ( !de ) {
00176
00177 return fUrgent;
00178 }
00179 it=fCounter.find(de);
00180 }
00181
00182 #ifdef DSFMSA_DEBUGPOSITION
00183 ii=tmpMap[it->first];
00184 if (ii==0){
00185 info()<<"found again strange de"<<endreq;
00186 }
00187 xx=aTrack->GetPosition().x();
00188 yy=aTrack->GetPosition().y();
00189 zz=aTrack->GetPosition().z();
00190 tree->Fill();
00191 if (ii==0) {
00192 G4VPhysicalVolume* v=aTrack->GetVolume();
00193 G4String name=v?v->GetName():"no volume";
00194 info()<<"strange volume"<<it->first->name()<<" "<<name.data()<<endreq;
00195 }
00196 #endif
00197
00198 DECounter& counter=it->second;
00199 counter++;
00200 G4double tweight=aTrack->GetWeight();
00201 if ( tweight>=counter.weight ) {
00202
00203
00204
00205 return fUrgent;
00206 }
00207
00208 if ( !counter.full() ) {
00209
00210 return fTrackRemainingPhotons?fUrgent:fWaiting;
00211 }
00212
00213 if( m_uni()>=1./counter.weight ) {
00214
00215 return fKill;
00216 }
00217
00218
00219 G4Track* track=const_cast<G4Track*>(aTrack);
00220 track->SetWeight(tweight*counter.weight);
00221 counter.nTracks++;
00222 return fUrgent;
00223 }
00224
00225 void DsFastMuonStackAction::NewStage()
00226 {
00227
00228
00229
00230
00231 std::map<IDetectorElement*, DECounter>::iterator it, end=fCounter.end();
00232 for ( it=fCounter.begin(); it!=end; it++ ) it->second.reset();
00233 fTrackRemainingPhotons=true;
00234 stackManager->ReClassify();
00235 fTrackRemainingPhotons=false;
00236
00237 }
00238
00239
00240 void DsFastMuonStackAction::PrepareNewEvent()
00241 {
00242 #ifdef DSFMSA_DEBUGPOSITION
00243 event++;
00244 #endif
00245 fTrackRemainingPhotons=false;
00246 std::map<IDetectorElement*, DECounter>::iterator it, end=fCounter.end();
00247 for ( it=fCounter.begin(); it!=end; it++ ){
00248 DECounter& c=it->second;
00249 if ( c.full() )
00250 info()<<c.nTracks<<" tracks for "<<
00251 c.count-c.maxCount<<" photons are simulated in "<<
00252 it->first->name()<<endreq;
00253
00254 c.reset(true);
00255 }
00256 }
00257
00258
00259