| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

DsFastMuonStackAction.cc

Go to the documentation of this file.
00001 /*
00002 A tool to weight photons based on the detector element.
00003 
00004 Usage:
00005     from DetSim.DetSimConf import DsFastMuonStackAction
00006     saction = DsFastMuonStackAction("GiGa.DsFastMuonStackAction")
00007     saction.Detectors = [ '/dd/Structure/DayaBay/db-rock/db-ows', 
00008                           '/dd/Structure/DayaBay/db-rock/db-ows/db-curtain/db-iws',
00009                           '/dd/Structure/DayaBay/db-rock/db-ows/db-curtain/db-iws/db-ade1/db-sst1/db-oil1',
00010                           '/dd/Structure/DayaBay/db-rock/db-ows/db-curtain/db-iws/db-ade2/db-sst2/db-oil2' ]
00011     saction.Limits = [ 10000, 10000, 10000, 10000 ]
00012     saction.10.s = [ 10., 10., 10., 10. ]
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     // set up random numbers
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     // Classify new track, and if it is a photon determine whether it should be weighted or not
00132     //
00133     if (aTrack->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition()) return fUrgent;
00134     //if ( fTrackRemainingPhotons )  info()<<"track remaining"<<endreq; //debug
00135 
00136     // 
00137     // Determine the whether the track is situated in interesting for us DE or not
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         // cached DE is not found
00146         // determine it and save to cache
00147         //
00148         // info()<<"  cached DE is not found"<<endreq;//debug
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             // iterate up through the hierarchy of detector elements, 
00154             // until we find the DE we are interested in,
00155             // or at least get to the top of the hierarchy
00156             de=de->parentIDetectorElement();    
00157             it=fCounter.find(de); 
00158         }
00159         //info()<<"  found "<<de<<" points to"<<(int)de<<" end:"<<(it==end)<<endreq;//debug
00160         if ( touchable ) fTouchablesCache[touchable]=de;
00161         else { 
00162             // G4VPhysicalVolume* v=aTrack->GetVolume();
00163             // G4String name=v?v->GetName():"no volume";
00164             // warning()<<"FastMuonStackAction got NULL touchable to '"<<name<<"'. Ignoring..."<<endreq;
00165             return fUrgent;
00166         }
00167         if ( !de ) {// point is not situated in any of DE we are interested in
00168             return fUrgent;
00169         }
00170     }
00171     else {
00172         // cached DE found
00173         // info()<<"  cache found"<<endreq;//debug
00174         de=cacheIt->second;
00175         if ( !de ) {
00176             // point is not situated in any of DE we are interested in
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         // ignore the tracks with high weight
00203         // even if it's logically correct
00204         // large weights are bad
00205         return fUrgent;
00206     }
00207 
00208     if ( !counter.full()  ) {
00209         //number of photons for this DE is small, continue collecting
00210         return fTrackRemainingPhotons?fUrgent:fWaiting;
00211     }
00212       
00213     if( m_uni()>=1./counter.weight ) { 
00214         //info()<<"killed"<<endreq;//debug
00215         return fKill; 
00216     }
00217     
00218     // info()<<"push weighted track"<<endreq;//debug
00219     G4Track* track=const_cast<G4Track*>(aTrack); //yes, it's ugly, but should be safe
00220     track->SetWeight(tweight*counter.weight);
00221     counter.nTracks++;
00222     return fUrgent;
00223 }
00224 
00225 void DsFastMuonStackAction::NewStage()
00226 {
00227     // 
00228     // The Urgent stack is empty. It means that all possible particles are simulated
00229     // except the photons, delayed fo several DEs.
00230     // info()<<"New stage, reclassifying"<<endreq;
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     //info()<<"Classification is finished"<<endreq;
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 //-----------------------END----------------------------------
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:53:23 2011 for DetSim by doxygen 1.4.7