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
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
00071
00072
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);
00168
00169 using namespace RuleParser;
00170 using std::string;
00171
00172
00173
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
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
00257
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();
00271 break;
00272 }
00273
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
00297 output = m_capinfo->getCapture().GetCapTargetZ();
00298
00299
00300
00301
00302
00303 break;
00304 case kPar_capTargetA:
00305
00306 output = m_capinfo->getCapture().GetCapTargetA();
00307
00308
00309 break;
00310
00311
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)
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
00516
00517
00518 const IDetectorElement* QueriableStepAction::getDetectorElement() const
00519 {
00520 if(!mDetElement) {
00521
00522
00523
00524
00525
00526
00527 if(mCurrentStep->GetPreStepPoint()->GetPhysicalVolume() == 0) {
00528 return 0;
00529 }
00530 if(mCurrentStep->GetPreStepPoint()->GetPhysicalVolume()->GetMotherLogical() == 0) {
00531 return 0;
00532 }
00533
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)
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
00609
00610 double dE = mCurrentStep->GetTotalEnergyDeposit();
00611 double dx = mCurrentStep->GetStepLength();
00612
00613
00614 mQuenchedEnergy = 0;
00615 if(dE > 0) {
00616 if(aParticle == G4Gamma::Gamma())
00617 {
00618 G4LossTableManager* manager = G4LossTableManager::Instance();
00619 dx = manager->GetRange(G4Electron::Electron(), dE, aTrack->GetMaterialCutsCouple());
00620
00621 }
00622 G4Material* aMaterial = mCurrentStep->GetPreStepPoint()->GetMaterial();
00623 G4MaterialPropertiesTable* aMaterialPropertiesTable =
00624 aMaterial->GetMaterialPropertiesTable();
00625 if (aMaterialPropertiesTable) {
00626
00627
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
00635 double delta = dE/dx/aMaterial->GetDensity();
00636
00637 double birk1 = m_BirksConstant1;
00638 if(mCurrentTrack->GetDefinition()->GetPDGCharge()>1.1)
00639 birk1 = 0.57*birk1;
00640
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
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
00680 mDetectorIdCache[de] = id;
00681
00682 return id;
00683 }
00684 }
00685 }
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
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 }