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

In This Package:

QueriableStepAction.cc

Go to the documentation of this file.
00001 #include "QueriableStepAction.h"
00002 #include "G4ToHistoryUtensils.h"
00003 #include "G4HistoryUserTrackInfo.h"
00004 #include "HistorianCustomRules.h"
00005 
00006 #include "G4TouchableHistory.hh"
00007 #include "G4TouchableHandle.hh"
00008 #include "G4Step.hh"
00009 #include "G4Track.hh"
00010 #include "G4StepPoint.hh"
00011 #include "G4SteppingManager.hh"
00012 #include "G4MaterialPropertiesTable.hh"
00013 #include "G4ParticleDefinition.hh"
00014 #include "G4LossTableManager.hh"
00015 #include "G4MaterialCutsCouple.hh"
00016 #include "G4Gamma.hh"
00017 #include "G4Electron.hh"
00018 
00019 #include "RuleParser/ParameterDescription.h"
00020 #include "RuleParser/PrescaleRule.h"
00021 
00022 #include "G4DataHelpers/ITouchableToDetectorElement.h"
00023 #include "DetDesc/IDetectorElement.h"
00024 #include "DetDesc/GeometryInfoPlus.h"
00025 #include "DetDesc/IPVolume.h"
00026 
00027 #include <vector>
00028 
00029 
00030 using namespace DayaBay;
00031 
00032 
00033 
00034 QueriableStepAction::QueriableStepAction ( 
00035   const std::string& type   , 
00036   const std::string& name   , 
00037   const IInterface*  parent ) 
00038   : GiGaStepActionBase( type , name , parent )
00039   , m_DetectorElementSearchPath(1,"/dd/Structure")
00040   , mCurrentStep(0)
00041   , mCurrentTrack(0)
00042   , mCurrentStepPoint(0)
00043   , mTouchToDetElem(0)
00044 { 
00045   declareProperty("TouchableToDetelem",m_TouchableToDetelem_name = "TH2DE");
00046   declareProperty("DetectorElementSearchPath",m_DetectorElementSearchPath);
00047 
00048   m_IdParameterNames.push_back("PmtID");
00049   m_IdParameterNames.push_back("DetectorID");
00050   m_IdParameterNames.push_back("SiteID");
00051   declareProperty("IdParameterNames",m_IdParameterNames,
00052                   "Names of the user parameters attached to detector elements used to give ID numbers.");
00053   
00054   // Liang Zhan, Jan 18, 2009.
00055   declareProperty("BirksConstant1", m_BirksConstant1 = 6.5e-3*g/cm2/MeV, "Birks constant C1");
00056   declareProperty("BirksConstant2", m_BirksConstant2 = 2.1e-6*(g/cm2/MeV)*(g/cm2/MeV), "Birks constant C2");
00057 }
00058 
00059 StatusCode QueriableStepAction::initialize() 
00060 {
00061   StatusCode sc =  GiGaStepActionBase::initialize();
00062   if(sc.isFailure()) return sc;
00063 
00064   std::string t2de_name = std::string("t2de_") + name();
00065   mTouchToDetElem = tool<ITouchableToDetectorElement>(
00066      m_TouchableToDetelem_name,
00067      name(),
00068      this);
00069 
00070   // Get the Neutron Capture tool which is updated in DsPhysConHadron.cc
00071   // to gain access to the neutron capture information.
00072   // --- Wei, Aug 15, 2008
00073   m_capinfo = tool<INeutronCaptureInfo>("G4DhNeutronCaptureInfoTool");
00074 
00075   verbose() << " QueriableStepAction::initialize() done" << endreq;
00076 
00077   return StatusCode::SUCCESS;
00078 }
00079 
00080 StatusCode QueriableStepAction::finalize() 
00081 {
00082   return  GiGaStepActionBase::finalize();
00083 }
00084 
00085 void QueriableStepAction::Reset(const G4Step* step, 
00086                                 const G4Track* track, 
00087                                 const G4StepPoint* point)
00088                                 
00089 {
00090   mCurrentStep = step;
00091   mCurrentTrack = track;
00092   mCurrentStepPoint = point;
00093   
00094   mDetElement=0;
00095   mDetElementMatch=-1;
00096   mLogicVolume=0;
00097   mPhysVolume=0;
00098   mProcess=SimProcess();
00099   mQuenchedEnergy = -1e9;
00100   mUserTrackInfo = 0;
00101   mDetectorId = 0xFFFFFFF;
00102 
00103   verbose() << " The current track has been reset " << endreq;
00104 }
00105 
00106 
00107 StatusCode  QueriableStepAction::GetTrackParameterList(RuleParser::ParameterList& tplist)
00108 {
00109   using namespace RuleParser;
00110   using std::string;
00111   
00112   tplist.add<double>(kPar_t,"time","t");
00113   tplist.add<double>(kPar_x,"x","global_x");
00114   tplist.add<double>(kPar_y,"y","global_y");
00115   tplist.add<double>(kPar_z,"z","global_z");
00116   tplist.add<double>(kPar_r,"r","radius","pos_r");
00117   tplist.add<double>(kPar_local_x,"lx","local_x","det_x");             
00118   tplist.add<double>(kPar_local_y,"ly","local_y","det_y");
00119   tplist.add<double>(kPar_local_z,"lz","local_z","det_z");
00120   tplist.add<double>(kPar_local_r,"lr","local_r","det_r");
00121   tplist.add<string>(kPar_LogicalVolumeName,"Volume","LogicalVolumeName","LogicalVolume","VolumeName");
00122   tplist.add<string>(kPar_MaterialName,"Material","MaterialName");
00123   tplist.add<string>(kPar_DetectorElementName,"DetectorElementName");
00124   tplist.add<double>(kPar_DetectorElementMatch,"Match","DetectorElementMatch");
00125   tplist.add<double>(kPar_NicheId,"NicheId","Niche");
00126   tplist.add<double>(kPar_DetectorId,"DetectorId");
00127   tplist.add<double>(kPar_SiteId,"SiteId");
00128   tplist.add<double>(kPar_Site,"Site");
00129   tplist.add<double>(kPar_AD,"AD","AdNumber");
00130 
00131   tplist.add<double>(kPar_momentum,"momentum","p");
00132   tplist.add<double>(kPar_TotEnergy,"E","totEnergy","TotalEnergy");
00133   tplist.add<double>(kPar_KineticEnergy,"KE","kineticEnergy");
00134   tplist.add<double>(kPar_vx,"vx","global_dir_x","global_u");
00135   tplist.add<double>(kPar_vy,"vy","global_dir_y","global_v");
00136   tplist.add<double>(kPar_vz,"vz","global_dir_z","global_w");
00137   tplist.add<double>(kPar_local_vx,"lvx","local_dir_x","local_u");
00138   tplist.add<double>(kPar_local_vy,"lvy","local_dir_y","local_v");
00139   tplist.add<double>(kPar_local_vz,"lvz","local_dir_z","local_w");
00140   tplist.add<double>(kPar_ProcessType,"ProcessType");
00141   tplist.add<string>(kPar_ProcessName,"Process","ProcessName");
00142   tplist.add<double>(kPar_Pdg,"pdg","pdgcode","particle");
00143   tplist.add<double>(kPar_Charge,"charge","ParticleCharge","q");
00144   tplist.add<double>(kPar_TrackId,"id","trackid");
00145   tplist.add<double>(kPar_CreatorPdg,"creatorPdg","creator");
00146   tplist.add<double>(kPar_AncestorPdg,"ParentPdg","AncestorPdg","Ancestor");
00147   tplist.add<double>(kPar_mass,"mass","m");
00148   tplist.add<string>(kPar_ParticleName,"ParticleName");
00149   tplist.add<string>(kPar_CreatorProcessName,"CreatorProcessName","CreatorProcess");
00150 
00151 
00152 
00153   boost::shared_ptr<RuleFactory> prescaleFactory(new PrescaleRuleFactory);
00154   boost::shared_ptr<RuleFactory> customFactory(new DetElemContainsRuleFactory<QueriableStepAction>(this));
00155   tplist.add<int>(kPar_Prescale,"Prescale","by",prescaleFactory);
00156   tplist.add<const IDetectorElement*>(kPar_DetectorElement,"DetElem","in",customFactory);
00157   tplist.add<const IDetectorElement*>(kPar_DetectorElement,"DetectorElement","in",customFactory);
00158 
00159 
00160   return StatusCode::SUCCESS;
00161 }
00162 
00163 
00164 StatusCode  QueriableStepAction::GetVertexParameterList(RuleParser::ParameterList& vplist)
00165 {
00167   GetTrackParameterList(vplist); // Everything valid for a track is valid for a vertex.
00168 
00169   using namespace RuleParser;
00170   using std::string;
00171 
00172 
00173   // And add vertex-specific stuff:
00174   vplist.add<double>(kPar_Step_dE,"Step_dE","dE");
00175   vplist.add<double>(kPar_Step_dE_Ion,"Step_dE_Ion","de_ion","ionization");
00176   vplist.add<double>(kPar_Step_qdE,"Step_qDE","quenched_dE","qdE");
00177   vplist.add<double>(kPar_Step_dx,"Step_dx","StepLength","dx");
00178   vplist.add<double>(kPar_Step_dt,"Step_dt","StepDuration","dt");
00179   vplist.add<double>(kPar_Step_dAngle,"Step_dAngle","dAngle");
00180   vplist.add<double>(kPar_capTargetZ,"capTargetZ");
00181   vplist.add<double>(kPar_capTargetA,"capTargetA");
00182   vplist.add<double>(kPar_Step_E_weighted_x,"Ex","E_weighted_x");
00183   vplist.add<double>(kPar_Step_E_weighted_y,"Ey","E_weighted_y"); 
00184   vplist.add<double>(kPar_Step_E_weighted_z,"Ez","E_weighted_z");    
00185   vplist.add<double>(kPar_Step_E_weighted_t,"Et","E_weighted_t");    
00186   vplist.add<double>(kPar_Step_qE_weighted_x,"qEx","qE_weighted_x","quenched_weighted_x");
00187   vplist.add<double>(kPar_Step_qE_weighted_y,"qEy","qE_weighted_y","quenched_weighted_y");    
00188   vplist.add<double>(kPar_Step_qE_weighted_z,"qEz","qE_weighted_z","quenched_weighted_z");    
00189   vplist.add<double>(kPar_Step_qE_weighted_t,"qEt","qE_weighted_t","quenched_weighted_t");                                     
00190 
00191 
00192   vplist.add<double>(kPar_IsStopping,"IsStopping","stop","End");
00193   vplist.add<double>(kPar_IsStarting,"IsStarting","start","begin");
00194   vplist.add<double>(kPar_StepNumber,"StepNumber");                    
00195   vplist.add<double>(kPar_VolumeChanged,"VolumeChanged","NewVolume");
00196   vplist.add<double>(kPar_MaterialChanged,"MaterialChanged","NewMaterial");
00197 
00198 
00199   verbose() << " kPar_MaterialName " << kPar_MaterialName << " kPar_MaterialChanged " << kPar_MaterialChanged
00200           << " kPar_VolumeChanged " << kPar_VolumeChanged << " kPar_Pdg " << kPar_Pdg 
00201           << " kPar_LogicalVolumeName " << kPar_LogicalVolumeName 
00202           << endreq;
00203   
00204   return StatusCode::SUCCESS;
00205 }                                                   
00206       
00207 
00208 
00210 // Callback functions for the RuleParser mechanism.
00211 void  QueriableStepAction::queryParam(int id,double& output) const
00212 {
00213 
00214   switch(id) {
00215     case kPar_IsStopping: 
00216       output = (  ( mCurrentTrack->GetTrackStatus() == fStopAndKill)
00217                || ( mCurrentTrack->GetTrackStatus() == fKillTrackAndSecondaries ) );
00218       break;
00219 
00220     case kPar_IsStarting: 
00221       output = (mCurrentTrack->GetCurrentStepNumber() == 1);
00222       break;
00223 
00224     case kPar_StepNumber:
00225       output = mCurrentTrack->GetCurrentStepNumber();
00226       break;
00227  
00228     case kPar_MaterialChanged:
00229       output = (mCurrentStep->GetPostStepPoint()->GetMaterial() != mCurrentStep->GetPreStepPoint()->GetMaterial());
00230       break;
00231 
00232     case kPar_VolumeChanged:
00233       output = (mCurrentStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary);
00234       break;
00235     
00236     case kPar_DetectorElementMatch:
00237       output = getDetectorElementMatch();
00238       break;
00239 
00240     case kPar_ProcessType:
00241       output = getProcess().type();
00242       break;
00243 
00244     case kPar_Pdg:
00245       output = mCurrentTrack->GetDefinition()->GetPDGEncoding();
00246       break;
00247 
00248     case kPar_Charge:
00249       output = mCurrentTrack->GetDefinition()->GetPDGCharge();
00250       break;
00251   
00252     case kPar_TrackId:
00253       output = mCurrentStep->GetTrack()->GetTrackID();
00254       break;
00255       
00256     // wangzhe
00257     // Help me track things.
00258     case kPar_CreatorPdg: {
00259       G4HistoryUserTrackInfo* userinfo = dynamic_cast<G4HistoryUserTrackInfo*>
00260         ( mCurrentStep->GetTrack()->GetUserInformation() );
00261       if(userinfo) 
00262         output = userinfo->parentPdg();
00263       break;
00264       }
00265       
00266     case kPar_AncestorPdg: {
00267       G4HistoryUserTrackInfo* userinfo = dynamic_cast<G4HistoryUserTrackInfo*>
00268         ( mCurrentStep->GetTrack()->GetUserInformation() );
00269       if(userinfo)
00270         output = userinfo->track().track()->particle(); // This will bring me to ancestor track
00271       break;
00272     }
00273     // wz
00274       
00275     case kPar_Step_dE:
00276       output = mCurrentStep->GetTotalEnergyDeposit();
00277       break;
00278     case kPar_Step_dE_Ion:
00279       output = mCurrentStep->GetTotalEnergyDeposit() - mCurrentStep->GetNonIonizingEnergyDeposit();
00280       break;
00281     case kPar_Step_qdE:
00282       output = getQuenchedEnergy();
00283       break;
00284     case kPar_Step_dx:
00285       output = mCurrentStep->GetStepLength();
00286       break;
00287     case kPar_Step_dt:
00288       output = mCurrentStep->GetDeltaTime();
00289       break;
00290     case kPar_Step_dAngle:
00291       output = acos(mCurrentStep->GetPostStepPoint()->GetMomentumDirection().dot(
00292                      mCurrentStep->GetPreStepPoint()->GetMomentumDirection())
00293                      ) * CLHEP::radian;
00294       break;
00295     case kPar_capTargetZ:
00296       // Return the neutron capture target Z
00297       output = m_capinfo->getCapture().GetCapTargetZ();
00298       //info()<<"stepAction: Z "<<m_capinfo->getCapture().GetCapTargetZ()
00299        //        <<" A: "<<m_capinfo->getCapture().GetCapTargetA()
00300         //       <<" time: "<<m_capinfo->getCapture().GetCapTime()
00301          //      <<" gammaNum: "<<m_capinfo->getCapture().GetCapGammaN()
00302           //     <<endreq;
00303       break;
00304     case kPar_capTargetA:
00305       // Return the neutron capture target A
00306       output = m_capinfo->getCapture().GetCapTargetA();
00307       //info()<<"stepAction: A"<<m_capinfo->getCapture().GetCapTargetA()
00308        //        <<endreq;               
00309       break;
00310       // For energy-weighted quantities, use the average position or time of the step rather than
00311       // the final position or time of the step.
00312     case kPar_Step_E_weighted_x:
00313       output = mCurrentStep->GetPreStepPoint()->GetPosition().x();
00314       if ( mCurrentStep->GetPostStepPoint() ) output = 0.5*(output + mCurrentStep->GetPostStepPoint()->GetPosition().x());
00315       output = mCurrentStep->GetTotalEnergyDeposit() * output;
00316       break;
00317     case kPar_Step_E_weighted_y:
00318       output = mCurrentStep->GetPreStepPoint()->GetPosition().y();
00319       if ( mCurrentStep->GetPostStepPoint() ) output = 0.5*(output + mCurrentStep->GetPostStepPoint()->GetPosition().y());
00320       output = mCurrentStep->GetTotalEnergyDeposit() * output;
00321       break;
00322     case kPar_Step_E_weighted_z:
00323       output = mCurrentStep->GetPreStepPoint()->GetPosition().z();
00324       if ( mCurrentStep->GetPostStepPoint() ) output = 0.5*(output + mCurrentStep->GetPostStepPoint()->GetPosition().z());
00325       output = mCurrentStep->GetTotalEnergyDeposit() * output;
00326       break;
00327     case kPar_Step_E_weighted_t:
00328       output = mCurrentStep->GetTotalEnergyDeposit() * mCurrentStepPoint->GetGlobalTime();
00329       output = mCurrentStep->GetPreStepPoint()->GetGlobalTime();
00330       if ( mCurrentStep->GetPostStepPoint() ) output = 0.5*(output + mCurrentStep->GetPostStepPoint()->GetGlobalTime());
00331       output = mCurrentStep->GetTotalEnergyDeposit() * output;
00332       break;
00333 
00334     case kPar_Step_qE_weighted_x:
00335       output = mCurrentStep->GetPreStepPoint()->GetPosition().x();
00336       if ( mCurrentStep->GetPostStepPoint() ) output = 0.5*(output + mCurrentStep->GetPostStepPoint()->GetPosition().x());
00337       output = getQuenchedEnergy() * output ; 
00338       break;
00339     case kPar_Step_qE_weighted_y:
00340       output = mCurrentStep->GetPreStepPoint()->GetPosition().y();
00341       if ( mCurrentStep->GetPostStepPoint() ) output = 0.5*(output + mCurrentStep->GetPostStepPoint()->GetPosition().y());
00342       output = getQuenchedEnergy() * output ; 
00343       break;    
00344     case kPar_Step_qE_weighted_z:
00345       output = mCurrentStep->GetPreStepPoint()->GetPosition().z();
00346       if ( mCurrentStep->GetPostStepPoint() ) output = 0.5*(output + mCurrentStep->GetPostStepPoint()->GetPosition().z());
00347       output = getQuenchedEnergy() * output ; 
00348       break;
00349     case kPar_Step_qE_weighted_t:
00350       output = mCurrentStep->GetPreStepPoint()->GetGlobalTime();
00351       if ( mCurrentStep->GetPostStepPoint() ) output = 0.5*(output + mCurrentStep->GetPostStepPoint()->GetGlobalTime());
00352       output = getQuenchedEnergy() * output ; 
00353       break;
00354 
00355     case kPar_t:
00356       output = mCurrentStepPoint->GetGlobalTime();
00357       break;
00358     case kPar_x:
00359       output = mCurrentStepPoint->GetPosition().x();
00360       break;    
00361     case kPar_y:
00362       output = mCurrentStepPoint->GetPosition().y();
00363       break;
00364     case kPar_z:
00365       output = mCurrentStepPoint->GetPosition().z();
00366       break;
00367     case kPar_r:
00368       output = sqrt(mCurrentStepPoint->GetPosition().x()*mCurrentStepPoint->GetPosition().x() +
00369                     mCurrentStepPoint->GetPosition().y()*mCurrentStepPoint->GetPosition().y());
00370       break;
00371 
00372     case kPar_local_x:
00373     case kPar_local_y:
00374     case kPar_local_z:
00375     case kPar_local_r:
00376     {
00377       const G4AffineTransform transformation =
00378         mCurrentStepPoint->GetTouchable()->GetHistory()->GetTopTransform();
00379       G4ThreeVector local = transformation.TransformPoint(mCurrentStepPoint->GetPosition());
00380       
00381       switch(id){
00382         case kPar_local_x: output = local.x(); break;
00383         case kPar_local_y: output = local.y(); break;
00384         case kPar_local_z: output = local.z(); break;
00385         case kPar_local_r: output = sqrt(local.x()*local.x() + local.y()*local.y()); break;        
00386       }
00387     }
00388     break;
00389     
00390     case kPar_NicheId:
00391       output = getDetectorId();
00392       break;
00393 
00394     case kPar_DetectorId:
00395       output = getDetectorId() & 0xFFFF0000;
00396       break;
00397     case kPar_SiteId:
00398       output = getDetectorId() & 0xFF000000;
00399       break;
00400     case kPar_AD:
00401       output = (getDetectorId() & 0x00FF0000) >> 16;
00402       break;
00403     case kPar_Site:
00404       output = (getDetectorId() & 0xFF000000) >> 24;
00405       break;
00406 
00407     case kPar_momentum:
00408        output = mCurrentStepPoint->GetMomentum().mag();
00409        break;
00410     case kPar_TotEnergy:
00411       output = mCurrentStepPoint->GetTotalEnergy();
00412       break;
00413     case kPar_KineticEnergy:
00414       output = mCurrentStepPoint->GetKineticEnergy();
00415       break;
00416     case kPar_mass:
00417       output = mCurrentStep->GetTrack()->GetDynamicParticle()->GetMass();
00418       break;
00419     case kPar_vx:
00420       output = mCurrentStepPoint->GetMomentumDirection().x();
00421       break;
00422     case kPar_vy:
00423       output = mCurrentStepPoint->GetMomentumDirection().y();
00424       break;
00425     case kPar_vz:
00426       output = mCurrentStepPoint->GetMomentumDirection().z();
00427       break;
00428 
00429     case kPar_local_vx:
00430     case kPar_local_vy:
00431     case kPar_local_vz:
00432     {
00433       const G4AffineTransform transformationV =
00434         mCurrentStepPoint->GetTouchable()->GetHistory()->GetTopTransform();
00435       G4ThreeVector localV = transformationV.TransformAxis(mCurrentStepPoint->GetMomentumDirection());
00436       
00437       switch(id){
00438         case kPar_local_vx: output = localV.x(); break;
00439         case kPar_local_vy: output = localV.y(); break;
00440         case kPar_local_vz: output = localV.z(); break;
00441       }
00442     }
00443     break;
00444         
00445     default:
00446       err() << "Unknown real parameter " << id << endreq;
00447       output = 0;
00448   }
00449   verbose() << " id " << id << " output " << output << endreq;
00450 
00451 }
00452 
00453 void  QueriableStepAction::queryParam(int id,std::string& output) const
00454 {
00455   const ILVolume* volume = 0;
00456   const IDetectorElement* ide = 0;
00457 
00458   switch(id) {
00459   case kPar_CreatorProcessName:
00460     if(mCurrentTrack->GetParentID()==0) // This is a primary.
00461         mProcess = SimProcess(SimProcess::kPrimaryVertex,"");
00462     else if(mCurrentTrack->GetCreatorProcess())
00463         mProcess = SimProcess(SimProcess::kParticleStart,mCurrentTrack->GetCreatorProcess()->GetProcessName());
00464     else
00465         mProcess = SimProcess(SimProcess::kParticleStart,""); 
00466     output = mProcess.name();
00467     verbose()<<" id " << id << " creator process name "<<output<<endreq;
00468     return;
00469     
00470   case kPar_ProcessName:
00471     switch(mCurrentStep->GetPostStepPoint()->GetStepStatus()) {
00472         case fWorldBoundary:   mProcess = SimProcess(SimProcess::kWorldBoundary,""); break;
00473         case fGeomBoundary:    mProcess = SimProcess(SimProcess::kGeomBoundary,""); break;
00474         default:
00475         SimProcessFromG4Process(mCurrentStep->GetPostStepPoint()->GetProcessDefinedStep(),mProcess);
00476     }
00477     output = mProcess.name();
00478     verbose()<<" id " << id << " process name "<<output<<endreq;
00479     return;
00480 
00481   case kPar_DetectorElementName:
00482     ide = getDetectorElement();
00483     if(ide)  output = ide->name();
00484     else output = "";
00485     verbose() << " id " << id << " detector element output " << output << endreq;
00486     return;
00487 
00488   case kPar_LogicalVolumeName:
00489     volume = getLogicalVolume();
00490     if(volume)  output = volume->name();
00491     else output = "";
00492     verbose() << " id " << id << " logical volume name output " << output << endreq;
00493     return;
00494     
00495   case kPar_MaterialName:
00496     volume = getLogicalVolume();
00497     if(volume)output = volume->materialName();
00498     else output ="";
00499     verbose() << " id " << id << " material name output " << output << endreq;
00500     return;
00501     
00502   case kPar_ParticleName:
00503     output = mCurrentStep->GetTrack()->GetDefinition()->GetParticleName();
00504     verbose() << " id " << id << " particle name output " << output << endreq;
00505     return;
00506     
00507   default:
00508     err() << "Unknown string parameter " << id << endreq;
00509     output = "";
00510   }
00511 }
00512 
00513 
00515 // Functions that get useful things and cache them
00516 // Note that current step point should be the pre step point for geometry, material, volume and detector element info
00517 
00518 const IDetectorElement* QueriableStepAction::getDetectorElement() const
00519 {
00520   if(!mDetElement) {
00521     // wangzhe:
00522     // (GetPhysicalVolume() == 0) at the boundary of the world.
00523     // (MotherLogical pointer == 0) means that current step point is
00524     // in the outmost volume, "Universe". 
00525     // Currently no touchable history info is available here, so neglect
00526     // any query in this volume.
00527     if(mCurrentStep->GetPreStepPoint()->GetPhysicalVolume() == 0) {
00528       return 0;
00529     }
00530     if(mCurrentStep->GetPreStepPoint()->GetPhysicalVolume()->GetMotherLogical() == 0) {
00531       return 0;
00532     }
00533     // wz
00534     G4VTouchable* touch = mCurrentStep->GetPreStepPoint()->GetTouchableHandle()();
00535     G4TouchableHistory* hist = dynamic_cast<G4TouchableHistory*>(touch);
00536     assert(hist);
00537 
00538     if (!hist->GetHistoryDepth()) {
00539         err() << "getDetectorElement(): given empty touchable history" << endreq;
00540         return 0;
00541     }
00542 
00543     StatusCode sc = mTouchToDetElem->GetBestDetectorElement(hist,
00544                                                             m_DetectorElementSearchPath,
00545                                                             mDetElement,
00546                                                             mDetElementMatch);
00547     if (sc.isFailure()) {
00548         err() << "Failed to get best detector element" << endreq;
00549         return 0;
00550     }
00551   }
00552   return mDetElement;  
00553 }
00554 
00555 int QueriableStepAction::getDetectorElementMatch() const
00556 {
00557   getDetectorElement();
00558   return mDetElementMatch;
00559 }
00560 
00561 const ILVolume* QueriableStepAction::getLogicalVolume() const
00562 {
00563   if(!mLogicVolume) {
00564     const IPVolume* pvol = getPhysicalVolume();
00565     if(pvol) mLogicVolume = pvol->lvolume();
00566   }
00567   return mLogicVolume; 
00568 }
00569 
00570 const IPVolume* QueriableStepAction::getPhysicalVolume() const
00571 {
00572   if(!mPhysVolume) {
00573      mTouchToDetElem->G4VolumeToDetDesc(mCurrentStep->GetPreStepPoint()->GetPhysicalVolume(),
00574                                         mPhysVolume
00575                                         );
00576    }
00577    return mPhysVolume;  
00578 }
00579 
00580 const SimProcess& QueriableStepAction::getProcess() const
00581 {
00582   if(!mProcess.isValid()){
00583     if(mCurrentStepPoint == mCurrentStep->GetPreStepPoint()) {
00584       if(mCurrentTrack->GetParentID()==0) // This is a primary.
00585          mProcess = SimProcess(SimProcess::kPrimaryVertex,"");
00586       else if(mCurrentTrack->GetCreatorProcess())
00587         mProcess = SimProcess(SimProcess::kParticleStart,mCurrentTrack->GetCreatorProcess()->GetProcessName());
00588       else
00589         mProcess = SimProcess(SimProcess::kParticleStart,"");
00590     } else {
00591       switch(mCurrentStep->GetPostStepPoint()->GetStepStatus()) {
00592         case fWorldBoundary:   mProcess = SimProcess(SimProcess::kWorldBoundary,""); break;
00593         case fGeomBoundary:    mProcess = SimProcess(SimProcess::kGeomBoundary,""); break;
00594         default:
00595         SimProcessFromG4Process(mCurrentStepPoint->GetProcessDefinedStep(),mProcess);
00596       }
00597     }
00598   }
00599   return mProcess;
00600 }
00601 
00602 double QueriableStepAction::getQuenchedEnergy() const
00603 {
00604   if(mQuenchedEnergy>=0) return mQuenchedEnergy;
00605   G4Track *aTrack = mCurrentStep->GetTrack();
00606   G4ParticleDefinition* aParticle = aTrack->GetDefinition();
00607   G4String particleName = aParticle->GetParticleName();
00608   //info()<<"particle name "<<particleName<<endreq;
00609 
00610   double dE = mCurrentStep->GetTotalEnergyDeposit();
00611   double dx = mCurrentStep->GetStepLength();
00612 
00613   // Find quenched energy deposit.
00614   mQuenchedEnergy = 0;
00615   if(dE > 0) {
00616     if(aParticle == G4Gamma::Gamma()) // It is a gamma
00617     {
00618       G4LossTableManager* manager = G4LossTableManager::Instance();
00619       dx = manager->GetRange(G4Electron::Electron(), dE, aTrack->GetMaterialCutsCouple());
00620       //info()<<"dE_dx = "<<dE/dx/(MeV/mm)<<"MeV/mm"<<endreq;
00621     } 
00622     G4Material* aMaterial = mCurrentStep->GetPreStepPoint()->GetMaterial();
00623     G4MaterialPropertiesTable* aMaterialPropertiesTable =
00624         aMaterial->GetMaterialPropertiesTable();
00625     if (aMaterialPropertiesTable) {
00626 
00627       // There are some properties. Is there a scintillator property?
00628       const G4MaterialPropertyVector* Fast_Intensity = 
00629           aMaterialPropertiesTable->GetProperty("FASTCOMPONENT"); 
00630       const G4MaterialPropertyVector* Slow_Intensity =
00631           aMaterialPropertiesTable->GetProperty("SLOWCOMPONENT");
00632   
00633       if (Fast_Intensity || Slow_Intensity ) {
00634         // It's a scintillator.
00635         double delta = dE/dx/aMaterial->GetDensity(); 
00636         //double birk1 = 0.0125*g/cm2/MeV;
00637         double birk1 = m_BirksConstant1; 
00638         if(mCurrentTrack->GetDefinition()->GetPDGCharge()>1.1)//for particle charge greater than 1.
00639            birk1 = 0.57*birk1;
00640         //double birk2 = (0.0031*g/MeV/cm2)*(0.0031*g/MeV/cm2);
00641         double birk2 = m_BirksConstant2;
00642         mQuenchedEnergy= dE /(1+birk1*delta+birk2*delta*delta);
00643       }
00644     }
00645   }
00646   return mQuenchedEnergy;  
00647 }
00648 
00649 const G4HistoryUserTrackInfo* QueriableStepAction::getUserTrackInfo() const
00650 {
00651   if(!mUserTrackInfo) {
00652     mUserTrackInfo = dynamic_cast<G4HistoryUserTrackInfo*>(mCurrentTrack->GetUserInformation());
00653   }
00654   return mUserTrackInfo;  
00655 }
00656 
00657 unsigned int QueriableStepAction::getDetectorId() const
00658 {
00659   if(mDetectorId==0xFFFFFFF) {
00660     const IDetectorElement* de = getDetectorElement();
00661     mDetectorId = getDetectorId(de);
00662   }
00663   return mDetectorId;
00664 }
00665 
00666 unsigned int QueriableStepAction::getDetectorId(const IDetectorElement* de) const
00667 {
00668   DetectorIdCache_t::iterator it = mDetectorIdCache.find(de);
00669   if(it!=mDetectorIdCache.end()) {
00670     return it->second;
00671   }
00672 
00673   const ParamValidDataObject* params = de->params();
00674   
00675   // Check each type of user param that the user could have provided:
00676   for(unsigned int ip = 0; ip<m_IdParameterNames.size(); ip++) {
00677     if (params->exists(m_IdParameterNames[ip])) {
00678       if (unsigned int id = (unsigned int)(params->param<int>(m_IdParameterNames[ip]))) {
00679         // Got it!
00680         mDetectorIdCache[de] = id;  // cache it for next time
00681         //info() << "Found id for " << getDetectorElement()->name() << " --> id " << std::hex << mDetectorId << std::dec << endreq;
00682         return id;
00683       }
00684     }
00685   }
00686   
00687   // Ok, we didnt' find it.
00688   // So, move up the support tree recursively.
00689 
00690   // --this does't work because geo->detElem() is private
00691   // const IGeometryInfo* igeo = de->geometry();
00692   //   ILVolume::ReplicaPath dummy;
00693   //   IGeometryInfo* nextGeo = 0;
00694   //   igeo->location(nextGeo, dummy); 
00695   //   if(nextGeo==0) return 0x0; // We failed to find any kind of ID.
00696   // const GeometryInfoPlus* geoplus = dynamic_cast<GeometryInfoPlus*>(nextGeo);
00697   //   assert(geoplus); // What's up with this?
00698   //   return getDetectorId(geoplus->detElem());
00699 
00700   // -- this works if the child elements are all set correctly in the XML.
00701   const IDetectorElement* nextElem = de->parentIDetectorElement();
00702   if(nextElem==0) {
00703     const IDetectorElement* ide = getDetectorElement();
00704     std::string DeName;
00705     if(ide) DeName = ide->name();
00706     else DeName = "";
00707     warning() << "Found no next-element for " << DeName << " --> id " << std::hex << mDetectorId << std::dec << endreq;
00708     mDetectorIdCache[de] = 0;
00709     return 0;
00710   }
00711   unsigned int id = getDetectorId(nextElem);
00712   mDetectorIdCache[de] = id;
00713   return id;
00714 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:54:53 2011 for Historian by doxygen 1.4.7