CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/SimG4CMS/Muon/src/MuonSensitiveDetector.cc

Go to the documentation of this file.
00001 #include "SimG4CMS/Muon/interface/MuonSensitiveDetector.h"
00002 #include "SimG4CMS/Muon/interface/MuonSlaveSD.h"
00003 #include "SimG4CMS/Muon//interface/MuonEndcapFrameRotation.h"
00004 #include "SimG4CMS/Muon/interface/MuonRpcFrameRotation.h"
00005 #include "Geometry/MuonNumbering/interface/MuonSubDetector.h"
00006 
00007 #include "DataFormats/GeometryVector/interface/LocalVector.h"
00008 
00009 #include "SimG4CMS/Muon/interface/SimHitPrinter.h"
00010 #include "SimDataFormats/TrackingHit/interface/UpdatablePSimHit.h"
00011 
00012 #include "SimG4CMS/Muon/interface/MuonG4Numbering.h"
00013 #include "Geometry/MuonNumbering/interface/MuonBaseNumber.h"
00014 #include "Geometry/MuonNumbering/interface/MuonSimHitNumberingScheme.h"
00015 
00016 #include "SimG4Core/Notification/interface/TrackInformation.h"
00017 #include "SimG4Core/Notification/interface/G4TrackToParticleID.h"
00018 #include "SimG4Core/Physics/interface/G4ProcessTypeEnumerator.h"
00019 
00020 #include "G4SDManager.hh"
00021 #include "G4VProcess.hh"
00022 #include "G4EventManager.hh"
00023 
00024 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00025 
00026 #include <iostream>
00027 
00028 
00029 MuonSensitiveDetector::MuonSensitiveDetector(std::string name, 
00030                                              const DDCompactView & cpv,
00031                                              SensitiveDetectorCatalog & clg,
00032                                              edm::ParameterSet const & p,
00033                                              const SimTrackManager* manager) 
00034   : SensitiveTkDetector(name, cpv, clg, p),
00035     thePV(0), theHit(0), theDetUnitId(0), theTrackID(0), theManager(manager)
00036 {
00037   edm::ParameterSet m_MuonSD = p.getParameter<edm::ParameterSet>("MuonSD");
00038   STenergyPersistentCut = m_MuonSD.getParameter<double>("EnergyThresholdForPersistency");//Default 1. GeV
00039   STallMuonsPersistent = m_MuonSD.getParameter<bool>("AllMuonsPersistent");
00040   printHits  = m_MuonSD.getParameter<bool>("PrintHits");
00041   
00042   //
00043   // Here simply create 1 MuonSlaveSD for the moment
00044   //  
00045   
00046   LogDebug("MuonSimDebug") << "create MuonSubDetector "<<name<<std::endl;
00047 
00048   detector = new MuonSubDetector(name);
00049 
00050   LogDebug("MuonSimDebug") << "create MuonFrameRotation"<<std::endl;
00051 
00052  if (detector->isEndcap()) {
00053    //    cout << "MuonFrameRotation create MuonEndcapFrameRotation"<<endl;
00054     theRotation=new MuonEndcapFrameRotation();
00055   } else if (detector->isRpc()) {
00056     //    cout << "MuonFrameRotation create MuonRpcFrameRotation"<<endl;
00057     theRotation=new MuonRpcFrameRotation( cpv );
00058   }  else {
00059     theRotation = 0;
00060   }
00061   LogDebug("MuonSimDebug") << "create MuonSlaveSD"<<std::endl;
00062   slaveMuon  = new MuonSlaveSD(detector,theManager);
00063   LogDebug("MuonSimDebug") << "create MuonSimHitNumberingScheme"<<std::endl;
00064   numbering  = new MuonSimHitNumberingScheme(detector, cpv);
00065   g4numbering = new MuonG4Numbering(cpv);
00066   
00067 
00068   //
00069   // Now attach the right detectors (LogicalVolumes) to me
00070   //
00071   std::vector<std::string>  lvNames = clg.logicalNames(name);
00072   this->Register();
00073   for (std::vector<std::string>::iterator it = lvNames.begin();  it != lvNames.end(); it++){
00074     LogDebug("MuonSimDebug") << name << " MuonSensitiveDetector:: attaching SD to LV " << *it << std::endl;
00075     this->AssignSD(*it);
00076   }
00077 
00078   if (printHits) {
00079     thePrinter = new SimHitPrinter("HitPositionOSCAR.dat");
00080   }
00081 
00082 
00083     LogDebug("MuonSimDebug") << "  EnergyThresholdForPersistency " << STenergyPersistentCut << " AllMuonsPersistent " <<  STallMuonsPersistent << std::endl;
00084     
00085     theG4ProcessTypeEnumerator = new G4ProcessTypeEnumerator;
00086     myG4TrackToParticleID = new G4TrackToParticleID;
00087 
00088 }
00089 
00090 
00091 MuonSensitiveDetector::~MuonSensitiveDetector() { 
00092   delete g4numbering;
00093   delete numbering;
00094   delete slaveMuon;
00095   delete theRotation;
00096   delete detector;
00097 
00098   delete theG4ProcessTypeEnumerator;
00099   
00100   delete myG4TrackToParticleID;
00101 }
00102 
00103 void MuonSensitiveDetector::update(const BeginOfEvent * i){
00104   clearHits();
00105 
00106   //----- Initialize variables to check if two steps belong to same hit
00107   thePV = 0;
00108   theDetUnitId = 0;
00109   theTrackID = 0;
00110 
00111 }
00112 
00113 void MuonSensitiveDetector::update(const  ::EndOfEvent * ev)
00114 {
00115   //slaveMuon->renumbering(theManager);
00116 }
00117 
00118 
00119 void MuonSensitiveDetector::clearHits()
00120 {
00121   LogDebug("MuonSimDebug") << "MuonSensitiveDetector::clearHits"<<std::endl;
00122   slaveMuon->Initialize();
00123 }
00124 
00125 bool MuonSensitiveDetector::ProcessHits(G4Step * aStep, G4TouchableHistory * ROhist)
00126 {
00127   LogDebug("MuonSimDebug") <<" MuonSensitiveDetector::ProcessHits "<<InitialStepPosition(aStep,WorldCoordinates)<<std::endl;
00128 
00129  // TimeMe t1( theHitTimer, false);
00130 
00131   if (aStep->GetTotalEnergyDeposit()>0.){
00132     // do not count neutrals that are killed by User Limits MinEKine
00133     if( aStep->GetTrack()->GetDynamicParticle()->GetCharge() != 0 ){
00134   
00135       if (newHit(aStep)) {
00136         saveHit();
00137         createHit(aStep);
00138       } else {
00139         updateHit(aStep);
00140       }    
00141       return true;
00142     } else {
00143       storeVolumeAndTrack(aStep);
00144       return false;
00145     }
00146   }
00147   return false;
00148 }
00149 
00150 uint32_t MuonSensitiveDetector::setDetUnitId(G4Step * aStep)
00151 { 
00152   //  G4VPhysicalVolume * pv = aStep->GetPreStepPoint()->GetPhysicalVolume();
00153   MuonBaseNumber num = g4numbering->PhysicalVolumeToBaseNumber(aStep);
00154   return numbering->baseNumberToUnitNumber(num);
00155 }
00156 
00157 
00158 Local3DPoint MuonSensitiveDetector::toOrcaRef(Local3DPoint in ,G4Step * s){
00159   if (theRotation !=0 ) {
00160     return theRotation->transformPoint(in,s);
00161   }
00162   return (in);
00163 }
00164 
00165 Local3DPoint MuonSensitiveDetector::toOrcaUnits(Local3DPoint in){
00166   return Local3DPoint(in.x()/cm,in.y()/cm,in.z()/cm);
00167 }
00168 
00169 Global3DPoint MuonSensitiveDetector::toOrcaUnits(Global3DPoint in){
00170   return Global3DPoint(in.x()/cm,in.y()/cm,in.z()/cm);
00171 }
00172 
00173 void MuonSensitiveDetector::storeVolumeAndTrack(G4Step * aStep)
00174 {
00175   G4VPhysicalVolume* pv = aStep->GetPreStepPoint()->GetPhysicalVolume();
00176   G4Track * t  = aStep->GetTrack();
00177   thePV=pv;
00178   theTrackID=t->GetTrackID();
00179 }
00180 
00181 bool MuonSensitiveDetector::newHit(G4Step * aStep){
00182   
00183   G4VPhysicalVolume* pv = aStep->GetPreStepPoint()->GetPhysicalVolume();
00184   G4Track * t  = aStep->GetTrack();
00185   uint32_t currentUnitId=setDetUnitId(aStep);
00186   unsigned int currentTrackID=t->GetTrackID();
00187   //unsigned int currentEventID=G4EventManager::GetEventManager()->GetConstCurrentEvent()->GetEventID();
00188   bool changed=((pv!=thePV) || 
00189                 (currentUnitId!=theDetUnitId) || 
00190                 (currentTrackID!=theTrackID));
00191   return changed;
00192 }
00193 
00194 void MuonSensitiveDetector::createHit(G4Step * aStep){
00195 
00196   G4Track * theTrack  = aStep->GetTrack(); 
00197 
00198   Local3DPoint theEntryPoint;
00199   Local3DPoint theExitPoint;
00200 
00201   if (detector->isBarrel()) {
00202     theEntryPoint= toOrcaUnits(toOrcaRef(InitialStepPositionVsParent(aStep,1),aStep)); // 1 level up
00203     theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPositionVsParent(aStep,1),aStep));  
00204   } else if (detector->isEndcap()) {
00205     // save local z at current level
00206     theEntryPoint= toOrcaUnits(toOrcaRef(InitialStepPosition(aStep,LocalCoordinates),aStep));
00207     theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPosition(aStep,LocalCoordinates),aStep));
00208     float zentry = theEntryPoint.z();
00209     float zexit = theExitPoint.z();
00210     Local3DPoint tempEntryPoint= toOrcaUnits(toOrcaRef(InitialStepPositionVsParent(aStep,4),aStep)); // 4 levels up
00211     Local3DPoint tempExitPoint= toOrcaUnits(toOrcaRef(FinalStepPositionVsParent(aStep,4),aStep));
00212     // reset local z from z wrt deep-parent volume to z wrt low-level volume
00213     theEntryPoint = Local3DPoint( tempEntryPoint.x(), tempEntryPoint.y(), zentry );
00214     theExitPoint  = Local3DPoint( tempExitPoint.x(), tempExitPoint.y(), zexit );
00215   } else {
00216     theEntryPoint= toOrcaUnits(toOrcaRef(InitialStepPosition(aStep,LocalCoordinates),aStep));
00217     theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPosition(aStep,LocalCoordinates),aStep)); 
00218   }
00219 
00220   float thePabs             = aStep->GetPreStepPoint()->GetMomentum().mag()/GeV;
00221   float theTof              = aStep->GetPreStepPoint()->GetGlobalTime()/nanosecond;
00222   float theEnergyLoss       = aStep->GetTotalEnergyDeposit()/GeV;
00223   //  int theParticleType     = theTrack->GetDefinition()->GetPDGEncoding();
00224   int theParticleType     = myG4TrackToParticleID->particleID(theTrack);
00225   G4ThreeVector gmd  = aStep->GetPreStepPoint()->GetMomentumDirection();
00226   G4ThreeVector lmd = ((G4TouchableHistory *)(aStep->GetPreStepPoint()->GetTouchable()))->GetHistory()
00227     ->GetTopTransform().TransformAxis(gmd);
00228   Local3DPoint lnmd = toOrcaRef(ConvertToLocal3DPoint(lmd),aStep);
00229   float theThetaAtEntry = lnmd.theta();
00230   float thePhiAtEntry = lnmd.phi();
00231 
00232   storeVolumeAndTrack( aStep );
00233   theDetUnitId              = setDetUnitId(aStep);
00234 
00235   Global3DPoint theGlobalPos;
00236   if (printHits) {   
00237     const G4RotationMatrix * theGlobalRot;
00238     Local3DPoint theGlobalHelp = InitialStepPosition(aStep,WorldCoordinates);
00239     theGlobalEntry = toOrcaUnits(Global3DPoint (theGlobalHelp.x(),theGlobalHelp.y(),theGlobalHelp.z()));
00240 
00241     G4StepPoint * preStepPoint = aStep->GetPreStepPoint();
00242     G4TouchableHistory * theTouchable=(G4TouchableHistory *)
00243                                       (preStepPoint->GetTouchable());
00244     theGlobalHelp=ConvertToLocal3DPoint(theTouchable->GetTranslation());
00245     theGlobalPos = toOrcaUnits(Global3DPoint (theGlobalHelp.x(),theGlobalHelp.y(),theGlobalHelp.z()));
00246     theGlobalRot = theTouchable->GetRotation();
00247   }
00248   
00249   LogDebug("MuonSimDebug") << "MuonSensitiveDetector::createHit UpdatablePSimHit"<<std::endl;
00250 
00251   theHit = new UpdatablePSimHit(theEntryPoint,theExitPoint,thePabs,theTof,
00252                   theEnergyLoss,theParticleType,theDetUnitId,
00253                   theTrackID,theThetaAtEntry,thePhiAtEntry,
00254                   theG4ProcessTypeEnumerator->processId(theTrack->GetCreatorProcess()));
00255 
00256 
00257   LogDebug("MuonSimDebug") <<"=== NEW ==================> ELOSS   = "<<theEnergyLoss<<" "
00258        <<thePV->GetLogicalVolume()->GetName()<<std::endl;
00259   const G4VProcess* p = aStep->GetPostStepPoint()->GetProcessDefinedStep();
00260   const G4VProcess* p2 = aStep->GetPreStepPoint()->GetProcessDefinedStep();
00261   if (p)
00262     LogDebug("MuonSimDebug") <<" POST PROCESS = "<<p->GetProcessName()<<std::endl;
00263   if (p2)
00264     LogDebug("MuonSimDebug") <<" PRE  PROCESS = "<<p2->GetProcessName()<<std::endl;
00265   LogDebug("MuonSimDebug") << "newhit theta " << theThetaAtEntry<<std::endl;
00266   LogDebug("MuonSimDebug") << "newhit phi   " << thePhiAtEntry<<std::endl;
00267   LogDebug("MuonSimDebug") << "newhit pabs  " << thePabs<<std::endl;
00268   LogDebug("MuonSimDebug") << "newhit tof   " << theTof<<std::endl;
00269   LogDebug("MuonSimDebug") << "newhit track " << theTrackID<<std::endl;
00270   LogDebug("MuonSimDebug") << "newhit entry " << theEntryPoint<<std::endl;
00271   LogDebug("MuonSimDebug") << "newhit exit  " << theExitPoint<<std::endl;
00272   LogDebug("MuonSimDebug") << "newhit eloss " << theEnergyLoss << std::endl;
00273   LogDebug("MuonSimDebug") << "newhit detid " << theDetUnitId<<std::endl;
00274   LogDebug("MuonSimDebug") << "newhit delta " << (theExitPoint-theEntryPoint)<<std::endl;
00275   LogDebug("MuonSimDebug") << "newhit deltu " << (theExitPoint-theEntryPoint).unit();
00276   LogDebug("MuonSimDebug") << " " << (theExitPoint-theEntryPoint).mag()<<std::endl;
00277   LogDebug("MuonSimDebug") << "newhit glob  " << theGlobalEntry<<std::endl;
00278   LogDebug("MuonSimDebug") << "newhit dpos  " << theGlobalPos<<std::endl;
00279   LogDebug("MuonSimDebug") << "newhit drot  " << std::endl;
00280   //  theGlobalRot->print(LogDebug("MuonSimDebug"));
00281 
00282 
00283   //
00284   //----- SimTracks: Make it persistent?
00285   //
00286   int thePID = theTrack->GetDefinition()->GetPDGEncoding();
00287   LogDebug("MuonSimDebug") << " checking simtrack " << thePID << " " << thePabs << " STenergyPersistentCut " << STenergyPersistentCut << std::endl;
00288 
00289   if( thePabs*GeV > STenergyPersistentCut 
00290       || ( abs(thePID) == 13 && STallMuonsPersistent ) ){
00291     TrackInformation* info = getOrCreateTrackInformation(theTrack);
00292     LogDebug("MuonSimDebug") <<" track leaving hit in muons made selected for persistency"<<std::endl;
00293 
00294     info->storeTrack(true);
00295   }
00296      
00297 }
00298 
00299 void MuonSensitiveDetector::updateHit(G4Step * aStep){
00300   //  float thePabs             = aStep->GetPreStepPoint()->GetMomentum().mag()/GeV;
00301   //  Local3DPoint theEntryPoint= InitialStepPosition(aStep,LocalCoordinates);  
00302 
00303 
00304   Local3DPoint theExitPoint;
00305 
00306   if (detector->isBarrel()) {
00307     theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPositionVsParent(aStep,1),aStep));  
00308   } else if (detector->isEndcap()) {
00309     // save local z at current level
00310     theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPosition(aStep,LocalCoordinates),aStep));
00311     float zexit = theExitPoint.z();
00312     Local3DPoint tempExitPoint= toOrcaUnits(toOrcaRef(FinalStepPositionVsParent(aStep,4),aStep));
00313     theExitPoint  = Local3DPoint( tempExitPoint.x(), tempExitPoint.y(), zexit );
00314   } else {
00315     theExitPoint= toOrcaUnits(toOrcaRef(FinalStepPosition(aStep,LocalCoordinates),aStep)); 
00316   }
00317 
00318   float theEnergyLoss = aStep->GetTotalEnergyDeposit()/GeV;  
00319 
00320   if( theHit == 0 ){ 
00321     std::cerr << "!!ERRROR in MuonSensitiveDetector::updateHit. It is called when there is no hit " << std::endl;
00322   }
00323 
00324   theHit->updateExitPoint(theExitPoint);
00325   theHit->addEnergyLoss(theEnergyLoss);
00326 
00327   LogDebug("MuonSimDebug") <<"=== UPDATE ===============> ELOSS   = "<<theEnergyLoss<<" "
00328        <<thePV->GetLogicalVolume()->GetName()<<std::endl;
00329   const G4VProcess* p = aStep->GetPostStepPoint()->GetProcessDefinedStep();
00330   const G4VProcess* p2 = aStep->GetPreStepPoint()->GetProcessDefinedStep();
00331   if (p)
00332     LogDebug("MuonSimDebug") <<" POST PROCESS = "<<p->GetProcessName()<<std::endl;
00333   if (p2)
00334     LogDebug("MuonSimDebug") <<" PRE  PROCESS = "<<p2->GetProcessName()<<std::endl;
00335   LogDebug("MuonSimDebug") << "updhit exit  " << theExitPoint<<std::endl;
00336   LogDebug("MuonSimDebug") << "updhit eloss " << theHit->energyLoss() <<std::endl;
00337   LogDebug("MuonSimDebug") << "updhit detid " << theDetUnitId<<std::endl;
00338   LogDebug("MuonSimDebug") << "updhit delta " << (theExitPoint-theHit->entryPoint())<<std::endl;
00339   LogDebug("MuonSimDebug") << "updhit deltu " << (theExitPoint-theHit->entryPoint()).unit();
00340   LogDebug("MuonSimDebug") << " " << (theExitPoint-theHit->entryPoint()).mag()<<std::endl; 
00341 
00342 }
00343 
00344 void MuonSensitiveDetector::saveHit(){
00345 
00346   if (theHit) {
00347     if (printHits) {
00348       thePrinter->startNewSimHit(detector->name());
00349       thePrinter->printId(theHit->detUnitId());
00350       //      thePrinter->printTrack(theHit->trackId());
00351       //thePrinter->printPabs(theHit->pabs());
00352       //thePrinter->printEloss(theHit->energyLoss());
00353       thePrinter->printLocal(theHit->entryPoint(),theHit->exitPoint());
00354       thePrinter->printGlobal(theGlobalEntry);
00355     }
00356     slaveMuon->processHits(*theHit);
00357     // seems the hit does not want to be deleted
00358     // done by the hit collection?
00359     delete theHit;
00360     theHit = 0; //set it to 0, because you are checking that is 0
00361   }
00362 
00363 }
00364 
00365 TrackInformation* MuonSensitiveDetector::getOrCreateTrackInformation( const G4Track* gTrack)
00366 {
00367   G4VUserTrackInformation* temp = gTrack->GetUserInformation();
00368   if (temp == 0){
00369     std::cerr <<" ERROR: no G4VUserTrackInformation available"<<std::endl;
00370     abort();
00371   }else{
00372     TrackInformation* info = dynamic_cast<TrackInformation*>(temp);
00373     if (info ==0){
00374       std::cerr <<" ERROR: TkSimTrackSelection: the UserInformation does not appear to be a TrackInformation"<<std::endl;
00375       abort();
00376     }
00377     return info;
00378   }
00379 }
00380 
00381 void MuonSensitiveDetector::EndOfEvent(G4HCofThisEvent*)
00382 {
00383 //  TimeMe t("MuonSensitiveDetector::EndOfEvent", false);
00384  // LogDebug("MuonSimDebug") << "MuonSensitiveDetector::EndOfEvent saving last hit en event " << std::endl;
00385   saveHit();
00386 }
00387 
00388 
00389 void MuonSensitiveDetector::fillHits(edm::PSimHitContainer& c, std::string n){
00390   //
00391   // do it once for low, once for High
00392   //
00393 
00394   if (slaveMuon->name() == n) c=slaveMuon->hits();
00395 
00396 }
00397 
00398 std::vector<std::string> MuonSensitiveDetector::getNames(){
00399   std::vector<std::string> temp;
00400   temp.push_back(slaveMuon->name());
00401   return temp;
00402 }
00403 
00404 Local3DPoint MuonSensitiveDetector::InitialStepPositionVsParent(G4Step * currentStep, G4int levelsUp) {
00405   
00406   G4StepPoint * preStepPoint = currentStep->GetPreStepPoint();
00407   G4ThreeVector globalCoordinates = preStepPoint->GetPosition();
00408   
00409   G4TouchableHistory * theTouchable=(G4TouchableHistory *)
00410     (preStepPoint->GetTouchable());
00411 
00412   G4int depth = theTouchable->GetHistory()->GetDepth();
00413   G4ThreeVector localCoordinates = theTouchable->GetHistory()
00414     ->GetTransform(depth-levelsUp).TransformPoint(globalCoordinates);
00415   
00416   return ConvertToLocal3DPoint(localCoordinates); 
00417 }
00418  
00419 Local3DPoint MuonSensitiveDetector::FinalStepPositionVsParent(G4Step * currentStep, G4int levelsUp) {
00420   
00421   G4StepPoint * postStepPoint = currentStep->GetPostStepPoint();
00422   G4StepPoint * preStepPoint  = currentStep->GetPreStepPoint();
00423   G4ThreeVector globalCoordinates = postStepPoint->GetPosition();
00424     
00425   G4TouchableHistory * theTouchable = (G4TouchableHistory *)
00426     (preStepPoint->GetTouchable());
00427 
00428   G4int depth = theTouchable->GetHistory()->GetDepth();
00429   G4ThreeVector localCoordinates = theTouchable->GetHistory()
00430     ->GetTransform(depth-levelsUp).TransformPoint(globalCoordinates);
00431 
00432   return ConvertToLocal3DPoint(localCoordinates); 
00433 }