CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/SimG4Core/GFlash/src/GflashEMShowerModel.cc

Go to the documentation of this file.
00001 //
00002 // initial setup : E.Barberio & Joanna Weng 
00003 // big changes : Soon Jun & Dongwook Jang
00004 //
00005 #include "SimG4Core/Application/interface/SteppingAction.h"
00006 #include "SimG4Core/GFlash/interface/GflashEMShowerModel.h"
00007 
00008 #include "SimGeneral/GFlash/interface/GflashEMShowerProfile.h"
00009 #include "SimGeneral/GFlash/interface/GflashHit.h"
00010 
00011 #include "G4Electron.hh"
00012 #include "G4Positron.hh"
00013 #include "G4VProcess.hh"
00014 #include "G4VPhysicalVolume.hh" 
00015 #include "G4LogicalVolume.hh"
00016 #include "G4TransportationManager.hh"
00017 #include "G4EventManager.hh"
00018 #include "G4FastSimulationManager.hh"
00019 #include "G4TouchableHandle.hh"
00020 #include "G4VSensitiveDetector.hh"
00021 
00022 GflashEMShowerModel::GflashEMShowerModel(const G4String& modelName, 
00023                                          G4Envelope* envelope, 
00024                                          const edm::ParameterSet& parSet)
00025   : G4VFastSimulationModel(modelName, envelope), theParSet(parSet) {
00026 
00027   //theWatcherOn = parSet.getParameter<bool>("watcherOn");
00028 
00029   theProfile = new GflashEMShowerProfile(parSet);
00030   theRegion  = const_cast<const G4Region*>(envelope); 
00031 
00032   theGflashStep = new G4Step();
00033   theGflashTouchableHandle = new G4TouchableHistory();
00034   theGflashNavigator = new G4Navigator();
00035 
00036 }
00037 
00038 // -----------------------------------------------------------------------------------
00039 
00040 GflashEMShowerModel::~GflashEMShowerModel() {
00041 
00042   delete theProfile;
00043   delete theGflashStep;
00044 }
00045 
00046 G4bool GflashEMShowerModel::IsApplicable(const G4ParticleDefinition& particleType) { 
00047 
00048   return ( &particleType == G4Electron::ElectronDefinition() ||
00049            &particleType == G4Positron::PositronDefinition() ); 
00050 
00051 }
00052 
00053 // -----------------------------------------------------------------------------------
00054 G4bool GflashEMShowerModel::ModelTrigger(const G4FastTrack & fastTrack ) {
00055 
00056   // Mininum energy cutoff to parameterize
00057   if(fastTrack.GetPrimaryTrack()->GetKineticEnergy() < GeV) { return false; }
00058   if(excludeDetectorRegion(fastTrack)) { return false; }
00059 
00060   // This will be changed accordingly when the way 
00061   // dealing with CaloRegion changes later.
00062   G4TouchableHistory* touch = 
00063     (G4TouchableHistory*)(fastTrack.GetPrimaryTrack()->GetTouchable());
00064   G4VPhysicalVolume* pCurrentVolume = touch->GetVolume();
00065   if( pCurrentVolume == 0) { return false; }
00066 
00067   G4LogicalVolume* lv = pCurrentVolume->GetLogicalVolume();
00068   if(lv->GetRegion() != theRegion) { return false; }
00069   //std::cout << "GflashEMShowerModel::ModelTrigger: LV " 
00070   //        << lv->GetRegion()->GetName() << std::endl;
00071 
00072   // The parameterization starts inside crystals
00073   //std::size_t pos1 = lv->GetName().find("EBRY");
00074   //std::size_t pos2 = lv->GetName().find("EFRY");
00075   
00076   //std::size_t pos3 = lv->GetName().find("HVQ");
00077   //std::size_t pos4 = lv->GetName().find("HF");
00078   //if(pos1 == std::string::npos && pos2 == std::string::npos &&
00079   //   pos3 == std::string::npos && pos4 == std::string::npos) return false;
00080   //@@@for now, HF is not a part of Gflash Envelopes
00081   //if(pos1 == std::string::npos && pos2 == std::string::npos ) return false;
00082 
00083   return true;
00084 
00085 }
00086 
00087 // -----------------------------------------------------------------------------------
00088 void GflashEMShowerModel::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep) {
00089 
00090   // Kill the parameterised particle:
00091   fastStep.KillPrimaryTrack();
00092   fastStep.ProposePrimaryTrackPathLength(0.0);
00093 
00094   //input variables for GflashEMShowerProfile with showerType = 1,5 (shower starts inside crystals)
00095   G4double energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy()/GeV;
00096   G4double globalTime = fastTrack.GetPrimaryTrack()->GetStep()->GetPostStepPoint()->GetGlobalTime();
00097   G4double charge = fastTrack.GetPrimaryTrack()->GetStep()->GetPreStepPoint()->GetCharge();
00098   G4ThreeVector position = fastTrack.GetPrimaryTrack()->GetPosition() / cm;
00099   G4ThreeVector momentum = fastTrack.GetPrimaryTrack()->GetMomentum()/GeV;
00100   G4int showerType = Gflash::findShowerType(position);
00101 
00102   // Do actual parameterization. The result of parameterization is gflashHitList
00103   theProfile->initialize(showerType,energy,globalTime,charge,position,momentum);
00104   theProfile->parameterization();
00105 
00106   //make hits
00107   makeHits(fastTrack);
00108 }
00109 
00110 void GflashEMShowerModel::makeHits(const G4FastTrack& fastTrack) {
00111 
00112   std::vector<GflashHit>& gflashHitList = theProfile->getGflashHitList();
00113 
00114   theGflashStep->SetTrack(const_cast<G4Track*>(fastTrack.GetPrimaryTrack()));
00115 
00116   theGflashStep->GetPostStepPoint()->SetProcessDefinedStep(const_cast<G4VProcess*>
00117     (fastTrack.GetPrimaryTrack()->GetStep()->GetPostStepPoint()->GetProcessDefinedStep()));
00118   theGflashNavigator->SetWorldVolume(G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume());
00119 
00120   std::vector<GflashHit>::const_iterator spotIter    = gflashHitList.begin();
00121   std::vector<GflashHit>::const_iterator spotIterEnd = gflashHitList.end();
00122 
00123   for( ; spotIter != spotIterEnd; spotIter++){
00124 
00125       //put touchable for each hit so that touchable history keeps track of each step.
00126       theGflashNavigator->LocateGlobalPointAndUpdateTouchableHandle(spotIter->getPosition(),G4ThreeVector(0,0,0),
00127                                                                     theGflashTouchableHandle, false);
00128       updateGflashStep(spotIter->getPosition(),spotIter->getTime());
00129 
00130       // if there is a watcher defined in a job and the flag is turned on
00131       if(theWatcherOn) {
00132         SteppingAction* userSteppingAction = (SteppingAction*) G4EventManager::GetEventManager()->GetUserSteppingAction();
00133         userSteppingAction->m_g4StepSignal(theGflashStep);
00134       }
00135 
00136       // Send G4Step information to Hit/Digi if the volume is sensitive
00137       // Copied from G4SteppingManager.cc
00138     
00139       G4VPhysicalVolume* aCurrentVolume = theGflashStep->GetPreStepPoint()->GetPhysicalVolume();
00140       if( aCurrentVolume == 0 ) continue;
00141 
00142       G4LogicalVolume* lv = aCurrentVolume->GetLogicalVolume();
00143       if(lv->GetRegion() != theRegion) continue;
00144 
00145       theGflashStep->GetPreStepPoint()->SetSensitiveDetector(aCurrentVolume->GetLogicalVolume()->GetSensitiveDetector());
00146       G4VSensitiveDetector* aSensitive = theGflashStep->GetPreStepPoint()->GetSensitiveDetector();
00147       
00148       if( aSensitive == 0 ) continue;
00149 
00150       theGflashStep->SetTotalEnergyDeposit(spotIter->getEnergy());
00151       aSensitive->Hit(theGflashStep);
00152   }
00153 
00154 }
00155 
00156 void GflashEMShowerModel::updateGflashStep(const G4ThreeVector& spotPosition, 
00157                                            G4double timeGlobal)
00158 {
00159   theGflashStep->GetPostStepPoint()->SetGlobalTime(timeGlobal);
00160   theGflashStep->GetPreStepPoint()->SetPosition(spotPosition);
00161   theGflashStep->GetPostStepPoint()->SetPosition(spotPosition);
00162   theGflashStep->GetPreStepPoint()->SetTouchableHandle(theGflashTouchableHandle);
00163 }
00164 
00165 // -----------------------------------------------------------------------------------
00166 G4bool GflashEMShowerModel::excludeDetectorRegion(const G4FastTrack& fastTrack) {
00167 
00168   G4bool isExcluded=false;
00169 
00170   //exclude regions where geometry are complicated
00171   //+- one supermodule around the EB/EE boundary: 1.479 +- 0.0174*5 
00172   G4double eta =   fastTrack.GetPrimaryTrack()->GetPosition().pseudoRapidity() ;
00173   if(std::fabs(eta) > 1.392 && std::fabs(eta) < 1.566) { return true; }
00174 
00175   return isExcluded;
00176 }
00177 
00178 /*
00179 G4int GflashEMShowerModel::findShowerType(const G4FastTrack& fastTrack)
00180 {
00181   // Initialization of longitudinal and lateral parameters for
00182   // hadronic showers. Simulation of the intrinsic fluctuations
00183 
00184   // type of hadron showers subject to the shower starting point (ssp)
00185   // showerType = -1 : default (invalid)
00186   // showerType =  0 : ssp before EBRY (barrel crystal)
00187   // showerType =  1 : ssp inside EBRY
00188   // showerType =  2 : ssp after  EBRY before HB
00189   // showerType =  3 : ssp inside HB
00190   // showerType =  4 : ssp before EFRY (endcap crystal)
00191   // showerType =  5 : ssp inside EFRY
00192   // showerType =  6 : ssp after  EFRY before HE
00193   // showerType =  7 : ssp inside HE
00194 
00195   G4TouchableHistory* touch = (G4TouchableHistory*)(fastTrack.GetPrimaryTrack()->GetTouchable());
00196   G4LogicalVolume* lv = touch->GetVolume()->GetLogicalVolume();
00197 
00198   std::size_t pos1  = lv->GetName().find("EBRY");
00199   std::size_t pos11 = lv->GetName().find("EWAL");
00200   std::size_t pos12 = lv->GetName().find("EWRA");
00201   std::size_t pos2  = lv->GetName().find("EFRY");
00202 
00203   G4ThreeVector position = fastTrack.GetPrimaryTrack()->GetPosition()/cm;
00204   Gflash::CalorimeterNumber kCalor = Gflash::getCalorimeterNumber(position);
00205 
00206   G4int showerType = -1;
00207 
00208   //central
00209   if (kCalor == Gflash::kESPM || kCalor == Gflash::kHB ) {
00210 
00211     G4double posRho = position.getRho();
00212 
00213     if(pos1 != std::string::npos || pos11 != std::string::npos || pos12 != std::string::npos ) {
00214       showerType = 1;
00215     }
00216     else {
00217       if(kCalor == Gflash::kESPM) {
00218         showerType = 2;
00219         if( posRho < Gflash::Rmin[Gflash::kESPM]+ Gflash::ROffCrystalEB ) showerType = 0;
00220       }
00221       else showerType = 3;
00222     }
00223 
00224   }
00225   //forward
00226   else if (kCalor == Gflash::kENCA || kCalor == Gflash::kHE) {
00227     if(pos2 != std::string::npos) {
00228       showerType = 5;
00229     }
00230     else {
00231       if(kCalor == Gflash::kENCA) {
00232         showerType = 6;
00233         if(fabs(position.getZ()) < Gflash::Zmin[Gflash::kENCA] + Gflash::ZOffCrystalEE) showerType = 4;
00234       }
00235       else showerType = 7;
00236     }
00237     //@@@need z-dependent correction on the mean energy reponse
00238   }
00239 
00240   return showerType;
00241 }
00242 */