G4ParallelWorldProcess.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id: G4ParallelWorldProcess.cc 69966 2013-05-21 09:52:06Z gcosmo $
00028 // GEANT4 tag $Name: geant4-09-04-ref-00 $
00029 //
00030 //
00031 
00032 #include "G4ios.hh"
00033 #include "G4ParallelWorldProcess.hh"
00034 #include "G4Step.hh"
00035 #include "G4StepPoint.hh"
00036 #include "G4Navigator.hh"
00037 #include "G4VTouchable.hh"
00038 #include "G4VPhysicalVolume.hh"
00039 #include "G4ParticleChange.hh"
00040 #include "G4PathFinder.hh"
00041 #include "G4TransportationManager.hh"
00042 #include "G4ParticleChange.hh"
00043 #include "G4StepPoint.hh"
00044 #include "G4FieldTrackUpdator.hh"
00045 #include "G4Material.hh"
00046 #include "G4ProductionCuts.hh"
00047 #include "G4ProductionCutsTable.hh"
00048 
00049 #include "G4SDManager.hh"
00050 #include "G4VSensitiveDetector.hh"
00051 
00052 G4Step* G4ParallelWorldProcess::fpHyperStep = 0;
00053 G4int   G4ParallelWorldProcess::nParallelWorlds = 0;
00054 G4int   G4ParallelWorldProcess::fNavIDHyp = 0;
00055 const G4Step* G4ParallelWorldProcess::GetHyperStep()
00056 { return fpHyperStep; }
00057 G4int G4ParallelWorldProcess::GetHypNavigatorID()
00058 { return fNavIDHyp; }
00059 
00060 G4ParallelWorldProcess::
00061 G4ParallelWorldProcess(const G4String& processName,G4ProcessType theType)
00062 :G4VProcess(processName,theType), fGhostNavigator(0), fNavigatorID(-1),
00063  fFieldTrack('0'),layeredMaterialFlag(false)
00064 {
00065   if(!fpHyperStep) fpHyperStep = new G4Step();
00066   iParallelWorld = ++nParallelWorlds;
00067 
00068   pParticleChange = &aDummyParticleChange;
00069 
00070   fGhostStep = new G4Step();
00071   fGhostPreStepPoint = fGhostStep->GetPreStepPoint();
00072   fGhostPostStepPoint = fGhostStep->GetPostStepPoint();
00073 
00074   fTransportationManager = G4TransportationManager::GetTransportationManager();
00075   fTransportationManager->GetNavigatorForTracking()->SetPushVerbosity(false);
00076   fPathFinder = G4PathFinder::GetInstance();
00077 
00078   if (verboseLevel>0)
00079   {
00080     G4cout << GetProcessName() << " is created " << G4endl;
00081   }
00082 }
00083 
00084 G4ParallelWorldProcess::~G4ParallelWorldProcess()
00085 {
00086   delete fGhostStep;
00087   nParallelWorlds--;
00088   if(nParallelWorlds==0)
00089   {
00090     delete fpHyperStep;
00091     fpHyperStep = 0;
00092   }
00093 }
00094 
00095 void G4ParallelWorldProcess::
00096 SetParallelWorld(G4String parallelWorldName)
00097 {
00098   fGhostWorldName = parallelWorldName;
00099   fGhostWorld = fTransportationManager->GetParallelWorld(fGhostWorldName);
00100   fGhostNavigator = fTransportationManager->GetNavigator(fGhostWorld);
00101   fGhostNavigator->SetPushVerbosity(false);
00102 }
00103 
00104 void G4ParallelWorldProcess::
00105 SetParallelWorld(G4VPhysicalVolume* parallelWorld)
00106 {
00107   fGhostWorldName = parallelWorld->GetName();
00108   fGhostWorld = parallelWorld;
00109   fGhostNavigator = fTransportationManager->GetNavigator(fGhostWorld);
00110   fGhostNavigator->SetPushVerbosity(false);
00111 }
00112 
00113 void G4ParallelWorldProcess::StartTracking(G4Track* trk)
00114 {
00115   if(fGhostNavigator)
00116   { fNavigatorID = fTransportationManager->ActivateNavigator(fGhostNavigator); }
00117   else
00118   {
00119     G4Exception("G4ParallelWorldProcess::StartTracking",
00120        "ProcParaWorld000",FatalException,
00121        "G4ParallelWorldProcess is used for tracking without having a parallel world assigned");
00122   }
00123   fPathFinder->PrepareNewTrack(trk->GetPosition(),trk->GetMomentumDirection());
00124 
00125   fOldGhostTouchable = fPathFinder->CreateTouchableHandle(fNavigatorID);
00126   fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
00127   fNewGhostTouchable = fOldGhostTouchable;
00128   fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
00129 
00130   fGhostSafety = -1.;
00131   fOnBoundary = false;
00132   fGhostPreStepPoint->SetStepStatus(fUndefined);
00133   fGhostPostStepPoint->SetStepStatus(fUndefined);
00134 
00135 //  G4VPhysicalVolume* thePhys = fNewGhostTouchable->GetVolume();
00136 //  if(thePhys)
00137 //  {
00138 //    G4Material* ghostMaterial = thePhys->GetLogicalVolume()->GetMaterial();
00139 //    if(ghostMaterial)
00140 //    { G4cout << " --- Material : " << ghostMaterial->GetName() << G4endl; }
00141 //  }
00142 
00143   *(fpHyperStep->GetPostStepPoint()) = *(trk->GetStep()->GetPostStepPoint());
00144   if(layeredMaterialFlag)
00145   {
00146     G4StepPoint* realWorldPostStepPoint = trk->GetStep()->GetPostStepPoint();
00147     SwitchMaterial(realWorldPostStepPoint);
00148   }
00149   *(fpHyperStep->GetPreStepPoint()) = *(fpHyperStep->GetPostStepPoint());
00150 }
00151 
00152 G4double 
00153 G4ParallelWorldProcess::AtRestGetPhysicalInteractionLength(
00154          const G4Track& /*track*/, 
00155          G4ForceCondition* condition)
00156 {
00157 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00158 // At Rest must be registered ONLY for the particle which has other At Rest
00159 // process(es).
00160 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00161   *condition = Forced;
00162   return DBL_MAX;
00163 }
00164 
00165 G4VParticleChange* G4ParallelWorldProcess::AtRestDoIt(
00166      const G4Track& track,
00167      const G4Step& step)
00168 { 
00169 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00170 // At Rest must be registered ONLY for the particle which has other At Rest
00171 // process(es).
00172 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00173   fOldGhostTouchable = fGhostPostStepPoint->GetTouchableHandle();
00174   G4VSensitiveDetector* aSD = 0;
00175   if(fOldGhostTouchable->GetVolume())
00176   { aSD = fOldGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector(); }
00177   fOnBoundary = false;
00178   if(aSD)
00179   {
00180     CopyStep(step);
00181     fGhostPreStepPoint->SetSensitiveDetector(aSD);
00182 
00183     fNewGhostTouchable = fOldGhostTouchable;
00184   
00185     fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
00186     fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
00187     if(fNewGhostTouchable->GetVolume())
00188     {
00189       fGhostPostStepPoint->SetSensitiveDetector(
00190         fNewGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector());
00191     }
00192     else
00193     { fGhostPostStepPoint->SetSensitiveDetector(0); }
00194 
00195     aSD->Hit(fGhostStep);
00196   }
00197 
00198   pParticleChange->Initialize(track);
00199   return pParticleChange;
00200 }
00201 
00202 G4double 
00203 G4ParallelWorldProcess::PostStepGetPhysicalInteractionLength(
00204          const G4Track& /*track*/, 
00205          G4double   /*previousStepSize*/, 
00206          G4ForceCondition* condition)
00207 {
00208   *condition = StronglyForced;
00209   return DBL_MAX;
00210 }
00211 
00212 G4VParticleChange* G4ParallelWorldProcess::PostStepDoIt(
00213      const G4Track& track,
00214      const G4Step& step)
00215 { 
00216   fOldGhostTouchable = fGhostPostStepPoint->GetTouchableHandle();
00217   G4VSensitiveDetector* aSD = 0;
00218   if(fOldGhostTouchable->GetVolume())
00219   { aSD = fOldGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector(); }
00220   CopyStep(step);
00221   fGhostPreStepPoint->SetSensitiveDetector(aSD);
00222 
00223   if(fOnBoundary)
00224   {
00225     fNewGhostTouchable = fPathFinder->CreateTouchableHandle(fNavigatorID);
00226   }
00227   else
00228   {
00229     fNewGhostTouchable = fOldGhostTouchable;
00230   }
00231     
00232   fGhostPreStepPoint->SetTouchableHandle(fOldGhostTouchable);
00233   fGhostPostStepPoint->SetTouchableHandle(fNewGhostTouchable);
00234 
00235   if(fNewGhostTouchable->GetVolume())
00236   {
00237     fGhostPostStepPoint->SetSensitiveDetector(
00238       fNewGhostTouchable->GetVolume()->GetLogicalVolume()->GetSensitiveDetector());
00239   }
00240   else
00241   { fGhostPostStepPoint->SetSensitiveDetector(0); }
00242 
00243   G4VSensitiveDetector* sd = fGhostPreStepPoint->GetSensitiveDetector();
00244   if(sd)
00245   {
00246     sd->Hit(fGhostStep);
00247   }
00248 
00249   pParticleChange->Initialize(track); 
00250   if(layeredMaterialFlag)
00251   {
00252     G4StepPoint* realWorldPostStepPoint =
00253      ((G4Step*)(track.GetStep()))->GetPostStepPoint();
00254     SwitchMaterial(realWorldPostStepPoint);
00255   }
00256   return pParticleChange;
00257 }
00258 
00259 G4double G4ParallelWorldProcess::AlongStepGetPhysicalInteractionLength(
00260             const G4Track& track, G4double  previousStepSize, G4double  currentMinimumStep,
00261             G4double& proposedSafety, G4GPILSelection* selection)
00262 {
00263   static G4FieldTrack endTrack('0');
00264   //static ELimited eLimited;
00265   ELimited eLimited;
00266   ELimited eLim = kUndefLimited;
00267   
00268   *selection = NotCandidateForSelection;
00269   G4double returnedStep = DBL_MAX;
00270 
00271   if (previousStepSize > 0.)
00272   { fGhostSafety -= previousStepSize; }
00273   if (fGhostSafety < 0.) fGhostSafety = 0.0;
00274       
00275   if (currentMinimumStep <= fGhostSafety && currentMinimumStep > 0.)
00276   {
00277     // I have no chance to limit
00278     returnedStep = currentMinimumStep;
00279     fOnBoundary = false;
00280     proposedSafety = fGhostSafety - currentMinimumStep;
00281     eLim = kDoNot;
00282   }
00283   else 
00284   {
00285     G4FieldTrackUpdator::Update(&fFieldTrack,&track);
00286     returnedStep
00287       = fPathFinder->ComputeStep(fFieldTrack,currentMinimumStep,fNavigatorID,
00288                      track.GetCurrentStepNumber(),fGhostSafety,eLimited,
00289                      endTrack,track.GetVolume());
00290     if(eLimited == kDoNot)
00291     {
00292       fOnBoundary = false;
00293       fGhostSafety = fGhostNavigator->ComputeSafety(endTrack.GetPosition());
00294     }
00295     else
00296     {
00297       fOnBoundary = true;
00298     }
00299     proposedSafety = fGhostSafety;
00300     if(eLimited == kUnique || eLimited == kSharedOther) {
00301        *selection = CandidateForSelection;
00302     }
00303     else if (eLimited == kSharedTransport) { 
00304        returnedStep *= (1.0 + 1.0e-9);  
00305     }
00306     eLim = eLimited;
00307   }
00308 
00309   if(iParallelWorld==nParallelWorlds) fNavIDHyp = 0;
00310   if(eLim == kUnique || eLim == kSharedOther) fNavIDHyp = fNavigatorID;
00311   return returnedStep;
00312 }
00313 
00314 G4VParticleChange* G4ParallelWorldProcess::AlongStepDoIt(
00315     const G4Track& track, const G4Step& )
00316 {
00317   pParticleChange->Initialize(track);
00318   return pParticleChange; 
00319 }
00320 
00321 void G4ParallelWorldProcess::CopyStep(const G4Step & step)
00322 {
00323   G4StepStatus prevStat = fGhostPostStepPoint->GetStepStatus();
00324 
00325   fGhostStep->SetTrack(step.GetTrack());
00326   fGhostStep->SetStepLength(step.GetStepLength());
00327   fGhostStep->SetTotalEnergyDeposit(step.GetTotalEnergyDeposit());
00328   fGhostStep->SetNonIonizingEnergyDeposit(step.GetNonIonizingEnergyDeposit());
00329   fGhostStep->SetControlFlag(step.GetControlFlag());
00330 
00331   *fGhostPreStepPoint = *(step.GetPreStepPoint());
00332   *fGhostPostStepPoint = *(step.GetPostStepPoint());
00333 
00334   fGhostPreStepPoint->SetStepStatus(prevStat);
00335   if(fOnBoundary)
00336   { fGhostPostStepPoint->SetStepStatus(fGeomBoundary); }
00337   else if(fGhostPostStepPoint->GetStepStatus()==fGeomBoundary)
00338   { fGhostPostStepPoint->SetStepStatus(fPostStepDoItProc); }
00339 
00340   if(iParallelWorld==1)
00341   {
00342     G4StepStatus prevStatHyp = fpHyperStep->GetPostStepPoint()->GetStepStatus();
00343 
00344     fpHyperStep->SetTrack(step.GetTrack());
00345     fpHyperStep->SetStepLength(step.GetStepLength());
00346     fpHyperStep->SetTotalEnergyDeposit(step.GetTotalEnergyDeposit());
00347     fpHyperStep->SetNonIonizingEnergyDeposit(step.GetNonIonizingEnergyDeposit());
00348     fpHyperStep->SetControlFlag(step.GetControlFlag());
00349 
00350     *(fpHyperStep->GetPreStepPoint()) = *(fpHyperStep->GetPostStepPoint());
00351     *(fpHyperStep->GetPostStepPoint()) = *(step.GetPostStepPoint());
00352   
00353     fpHyperStep->GetPreStepPoint()->SetStepStatus(prevStatHyp);
00354   }
00355 
00356   if(fOnBoundary)
00357   { fpHyperStep->GetPostStepPoint()->SetStepStatus(fGeomBoundary); }
00358 }
00359 
00360 void G4ParallelWorldProcess::SwitchMaterial(G4StepPoint* realWorldStepPoint)
00361 {
00362   if(realWorldStepPoint->GetStepStatus()==fWorldBoundary) return;
00363   G4VPhysicalVolume* thePhys = fNewGhostTouchable->GetVolume();
00364   if(thePhys)
00365   {
00366     G4Material* ghostMaterial = thePhys->GetLogicalVolume()->GetMaterial();
00367     if(ghostMaterial)
00368     {
00369       G4Region* ghostRegion = thePhys->GetLogicalVolume()->GetRegion();
00370       G4ProductionCuts* prodCuts =
00371           realWorldStepPoint->GetMaterialCutsCouple()->GetProductionCuts();
00372       if(ghostRegion)
00373       {
00374         G4ProductionCuts* ghostProdCuts = ghostRegion->GetProductionCuts();
00375         if(ghostProdCuts) prodCuts = ghostProdCuts;
00376       }
00377       const G4MaterialCutsCouple* ghostMCCouple =
00378           G4ProductionCutsTable::GetProductionCutsTable()
00379           ->GetMaterialCutsCouple(ghostMaterial,prodCuts);
00380       if(ghostMCCouple)
00381       {
00382         realWorldStepPoint->SetMaterial(ghostMaterial);
00383         realWorldStepPoint->SetMaterialCutsCouple(ghostMCCouple);
00384         *(fpHyperStep->GetPostStepPoint()) = *(fGhostPostStepPoint);
00385         fpHyperStep->GetPostStepPoint()->SetMaterial(ghostMaterial);
00386         fpHyperStep->GetPostStepPoint()->SetMaterialCutsCouple(ghostMCCouple);
00387       }
00388       else
00389       {
00390         G4cout << "!!! MaterialCutsCouple is not found for "
00391                << ghostMaterial->GetName() << "." << G4endl
00392                << "    Material in real world ("
00393                << realWorldStepPoint->GetMaterial()->GetName()
00394                << ") is used." << G4endl;
00395       }
00396     }
00397   }
00398 }
00399 
00400 G4bool G4ParallelWorldProcess::IsAtRestRequired(G4ParticleDefinition* partDef)
00401 {
00402   G4int pdgCode = partDef->GetPDGEncoding();
00403   if(pdgCode==0)
00404   {
00405     G4String partName = partDef->GetParticleName();
00406     if(partName=="opticalphoton") return false;
00407     if(partName=="geantino") return false;
00408     if(partName=="chargedgeantino") return false;
00409   }
00410   else
00411   {
00412     if(pdgCode==22) return false; // gamma
00413     if(pdgCode==11) return false; // electron
00414     if(pdgCode==2212) return false; // proton
00415     if(pdgCode==-12) return false; // anti_nu_e
00416     if(pdgCode==12) return false; // nu_e
00417     if(pdgCode==-14) return false; // anti_nu_mu
00418     if(pdgCode==14) return false; // nu_mu
00419     if(pdgCode==-16) return false; // anti_nu_tau
00420     if(pdgCode==16) return false; // nu_tau
00421   }
00422   return true;
00423 }
00424 

Generated on Mon May 27 17:49:14 2013 for Geant4 by  doxygen 1.4.7