CMS 3D CMS Logo

GflashHadronShowerModel.cc

Go to the documentation of this file.
00001 #include "SimG4Core/GFlash/interface/GflashHadronShowerModel.h"
00002 #include "SimG4Core/GFlash/interface/GflashHadronShowerProfile.h"
00003 #include "SimG4Core/GFlash/interface/GflashEnergySpot.h"
00004 #include "SimG4Core/GFlash/interface/GflashHistogram.h"
00005 
00006 #include "G4VSensitiveDetector.hh"
00007 #include "G4VPhysicalVolume.hh"
00008 
00009 #include "G4PionMinus.hh"
00010 #include "G4PionPlus.hh"
00011 #include "G4TransportationManager.hh"
00012 #include "G4TouchableHandle.hh"
00013 #include "G4VProcess.hh"
00014 #include "G4RegionStore.hh"
00015 #include "G4FastSimulationManager.hh"
00016 
00017 #include <vector>
00018 
00019 #include "SimG4Core/GFlash/interface/GflashTrajectory.h"
00020 #include "SimG4Core/GFlash/interface/GflashTrajectoryPoint.h"
00021 
00022 GflashHadronShowerModel::GflashHadronShowerModel(G4String modelName, G4Region* envelope)
00023   : G4VFastSimulationModel(modelName, envelope)
00024 {
00025   theProfile = new GflashHadronShowerProfile(envelope);
00026   theHisto = GflashHistogram::instance();
00027 
00028   theGflashStep = new G4Step();
00029   theGflashNavigator = new G4Navigator();
00030   theGflashTouchableHandle = new G4TouchableHistory();
00031 
00032   theGflashNavigator->SetWorldVolume(G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume());
00033 
00034 }
00035 
00036 GflashHadronShowerModel::~GflashHadronShowerModel()
00037 {
00038   if(theProfile) delete theProfile;
00039   if(theGflashStep) delete theGflashStep;
00040 }
00041 
00042 G4bool GflashHadronShowerModel::IsApplicable(const G4ParticleDefinition& particleType)
00043 {
00044   return 
00045     &particleType == G4PionMinus::PionMinusDefinition() ||
00046     &particleType == G4PionPlus::PionPlusDefinition();
00047 }
00048 
00049 G4bool GflashHadronShowerModel::ModelTrigger(const G4FastTrack& fastTrack)
00050 {
00051   // ModelTrigger returns false for Gflash Hadronic Shower Model if it is not
00052   // tested from the corresponding wrapper process, GflashHadronWrapperProcess. 
00053   // Temporarily the track status is set to fPostponeToNextEvent at the wrapper
00054   // process before ModelTrigger is really tested for the second time through 
00055   // PostStepGPIL of enviaged parameterization processes.  The better 
00056   // implmentation may be using via G4VUserTrackInformation of each track, which
00057   // requires to modify a geant source code of stepping (G4SteppingManager2)
00058 
00059   G4bool trigger = false;
00060 
00061   // mininum energy cutoff to parameterize
00062   if (fastTrack.GetPrimaryTrack()->GetKineticEnergy() < 1.0*GeV) return trigger;
00063 
00064   // check whether this is called from the normal GPIL or the wrapper process GPIL
00065   if(fastTrack.GetPrimaryTrack()->GetTrackStatus() == fPostponeToNextEvent ) {
00066 
00067     // Shower pameterization start at the first inelastic interaction point
00068     G4bool isInelastic  = isFirstInelasticInteraction(fastTrack);
00069     
00070     // Other conditions
00071     if(isInelastic) {
00072       trigger = (!excludeDetectorRegion(fastTrack));
00073     }
00074   }
00075 
00076   return trigger;
00077 
00078 }
00079 
00080 void GflashHadronShowerModel::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep)
00081 {
00082   // Kill the parameterised particle:
00083 
00084   fastStep.ProposeTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->GetKineticEnergy());
00085 
00086   // Parameterize shower shape and get resultant energy spots
00087   theProfile->clearSpotList();
00088   theProfile->hadronicParameterization(fastTrack);
00089 
00090   std::vector<GflashEnergySpot>& energySpotList = theProfile->getEnergySpotList();
00091 
00092   // Make hits
00093   G4double timeGlobal = fastTrack.GetPrimaryTrack()->GetStep()->GetPreStepPoint()->GetGlobalTime();
00094   
00095   std::vector<GflashEnergySpot>::const_iterator spotIter    = energySpotList.begin();
00096   std::vector<GflashEnergySpot>::const_iterator spotIterEnd = energySpotList.end();
00097   
00098    for( ; spotIter != spotIterEnd; spotIter++){
00099 
00100     // to make a different time for each fake step. (+1.0 is arbitrary)
00101     timeGlobal += 0.0001*nanosecond;
00102 
00103     // fill equivalent changes to a (fake) step associated with a spot 
00104 
00105     theGflashStep->SetTrack(const_cast<G4Track*>(fastTrack.GetPrimaryTrack()));
00106     theGflashStep->GetPostStepPoint()->SetGlobalTime(timeGlobal);
00107     theGflashStep->GetPreStepPoint()->SetPosition(spotIter->getPosition());
00108     theGflashStep->GetPostStepPoint()->SetPosition(spotIter->getPosition());
00109     theGflashStep->GetPostStepPoint()->SetProcessDefinedStep(const_cast<G4VProcess*> (fastTrack.GetPrimaryTrack()->GetStep()->GetPostStepPoint()->GetProcessDefinedStep()));
00110 
00111     //put touchable for each energy spot
00112     theGflashNavigator->LocateGlobalPointAndUpdateTouchable(spotIter->getPosition(),theGflashTouchableHandle(), false);
00113     theGflashStep->GetPreStepPoint()->SetTouchableHandle(theGflashTouchableHandle);
00114     theGflashStep->SetTotalEnergyDeposit(spotIter->getEnergy());
00115     
00116     // Send G4Step information to Hit/Dig if the volume is sensitive
00117     // Copied from G4SteppingManager.cc
00118 
00119     G4VPhysicalVolume* aCurrentVolume = theGflashStep->GetPreStepPoint()->GetPhysicalVolume();
00120 
00121     if( aCurrentVolume != 0 ) {
00122       theGflashStep->GetPreStepPoint()->SetSensitiveDetector(aCurrentVolume->GetLogicalVolume()->GetSensitiveDetector());
00123       G4VSensitiveDetector* aSensitive = theGflashStep->GetPreStepPoint()->GetSensitiveDetector();
00124       
00125       if( aSensitive != 0 ) {
00126         aSensitive->Hit(theGflashStep);
00127       }
00128     }
00129   }
00130 
00131   fastStep.KillPrimaryTrack();
00132   fastStep.ProposePrimaryTrackPathLength(0.0);
00133 
00134 }
00135 
00136 G4bool GflashHadronShowerModel::isFirstInelasticInteraction(const G4FastTrack& fastTrack)
00137 {
00138   G4bool isFirst=false;
00139 
00140   G4StepPoint* preStep = fastTrack.GetPrimaryTrack()->GetStep()->GetPreStepPoint();
00141   G4StepPoint* postStep = fastTrack.GetPrimaryTrack()->GetStep()->GetPostStepPoint();
00142 
00143   G4String procName = postStep->GetProcessDefinedStep()->GetProcessName();  
00144   G4ParticleDefinition* particleType = fastTrack.GetPrimaryTrack()->GetDefinition();
00145 
00146   //@@@ this part is still temporary and the cut for the variable ratio should be optimized later
00147 
00148   if((particleType == G4PionPlus::PionPlusDefinition() && procName == "WrappedPionPlusInelastic") || 
00149      (particleType == G4PionMinus::PionMinusDefinition() && procName == "WrappedPionMinusInelastic")) {
00150 
00151     G4double energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
00152 
00153     G4double ratio = 0.0;
00154     if (energy > 0) {
00155       ratio = fabs(fastTrack.GetPrimaryTrack()->GetStep()->GetDeltaEnergy()/energy);
00156     }
00157 
00158     if(ratio > 0.1) isFirst=true;
00159 
00160     //Fill debugging histograms and check information on secondaries -
00161     //remove after final implimentation
00162 
00163     if(theHisto->getStoreFlag()) {
00164       theHisto->preStepPosition->Fill(preStep->GetPosition().getRho()/cm);
00165       theHisto->postStepPosition->Fill(postStep->GetPosition().getRho()/cm);
00166       theHisto->deltaStep->Fill((postStep->GetPosition() - preStep->GetPosition()).getRho()/cm);
00167       theHisto->kineticEnergy->Fill(energy);
00168       theHisto->energyLoss->Fill(fabs(fastTrack.GetPrimaryTrack()->GetStep()->GetDeltaEnergy()/GeV));
00169     }
00170 
00171  }
00172   return isFirst;
00173 } 
00174 
00175 G4bool GflashHadronShowerModel::excludeDetectorRegion(const G4FastTrack& fastTrack)
00176 {
00177   G4bool isExcluded=false;
00178   
00179   //exclude regions where geometry are complicated 
00180   G4double eta =   fastTrack.GetPrimaryTrack()->GetMomentum().pseudoRapidity() ;
00181   if(fabs(eta) > 1.30 && fabs(eta) < 1.57) {
00182     std::cout << "excluding region of eta = " << eta << std::endl;
00183     return true;  
00184   }
00185   //exclude the region where the shower starting point is too close to the end of 
00186   //the hadronic envelopes (may need to be optimized further!)
00187 
00188   /*
00189   Gflash::CalorimeterNumber kColor = theProfile->getCalorimeterNumber(fastTrack);
00190 
00191   //@@@ need a proper scale
00192   const G4double minDistantToOut = 10.;
00193   
00194 
00195   if(kColor == kHB || kColor == kHE) {
00196     G4double distOut = fastTrack.GetEnvelopeSolid()->
00197       DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),
00198                     fastTrack.GetPrimaryTrackLocalDirection());
00199 
00200     if (distOut < minDistantToOut ) {
00201       std::cout << "excluding region for dsitOut = " << distOut << std::endl;
00202       isExcluded = true;
00203     }
00204   }
00205   */
00206 
00207   return isExcluded;
00208 }

Generated on Tue Jun 9 17:47:05 2009 for CMSSW by  doxygen 1.5.4