File indexing completed on 2024-09-10 02:59:07
0001
0002
0003
0004
0005
0006
0007
0008 #include "SimG4Core/SensitiveDetector/interface/FrameRotation.h"
0009 #include "SimG4Core/Notification/interface/TrackInformation.h"
0010 #include "SimG4Core/Notification/interface/G4TrackToParticleID.h"
0011 #include "SimG4Core/Physics/interface/G4ProcessTypeEnumerator.h"
0012
0013 #include "SimDataFormats/SimHitMaker/interface/TrackingSlaveSD.h"
0014 #include "SimDataFormats/TrackingHit/interface/UpdatablePSimHit.h"
0015 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
0016
0017 #include "SimG4CMS/FP420/interface/FP420SD.h"
0018 #include "SimG4CMS/FP420/interface/FP420G4Hit.h"
0019 #include "SimG4CMS/FP420/interface/FP420G4HitCollection.h"
0020 #include "SimG4CMS/FP420/interface/FP420NumberingScheme.h"
0021
0022 #include "FWCore/Framework/interface/EventSetup.h"
0023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0024 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0025
0026 #include "SimG4Core/Notification/interface/TrackInformation.h"
0027 #include "SimG4Core/Notification/interface/SimTrackManager.h"
0028
0029 #include "G4Track.hh"
0030 #include "G4SDManager.hh"
0031 #include "G4VProcess.hh"
0032 #include "G4EventManager.hh"
0033 #include "G4Step.hh"
0034 #include "G4ParticleTable.hh"
0035
0036 #include <CLHEP/Units/SystemOfUnits.h>
0037
0038 #include <string>
0039 #include <vector>
0040 #include <iostream>
0041
0042 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0043
0044
0045
0046 FP420SD::FP420SD(const std::string& name,
0047 const SensitiveDetectorCatalog& clg,
0048 edm::ParameterSet const& p,
0049 const SimTrackManager* manager)
0050 : SensitiveTkDetector(name, clg),
0051 numberingScheme(nullptr),
0052 hcID(-1),
0053 theHC(nullptr),
0054 theManager(manager),
0055 currentHit(nullptr),
0056 theTrack(nullptr),
0057 currentPV(nullptr),
0058 unitID(0),
0059 previousUnitID(0),
0060 preStepPoint(nullptr),
0061 postStepPoint(nullptr),
0062 eventno(0) {
0063
0064 edm::ParameterSet m_p = p.getParameter<edm::ParameterSet>("FP420SD");
0065 int verbn = m_p.getUntrackedParameter<int>("Verbosity");
0066
0067
0068 SetVerboseLevel(verbn);
0069
0070 slave = new TrackingSlaveSD(name);
0071
0072 if (name == "FP420SI") {
0073 if (verbn > 0) {
0074 edm::LogInfo("FP420Sim") << "name = FP420SI and new FP420NumberingSchem";
0075 }
0076 numberingScheme = new FP420NumberingScheme();
0077 } else {
0078 edm::LogWarning("FP420Sim") << "FP420SD: ReadoutName not supported\n";
0079 }
0080 }
0081
0082 FP420SD::~FP420SD() {
0083 delete slave;
0084 delete numberingScheme;
0085 }
0086
0087 double FP420SD::getEnergyDeposit(G4Step* aStep) { return aStep->GetTotalEnergyDeposit(); }
0088
0089 void FP420SD::Initialize(G4HCofThisEvent* HCE) {
0090 #ifdef debug
0091 LogDebug("FP420Sim") << "FP420SD : Initialize called for " << name << std::endl;
0092 #endif
0093
0094 theHC = new FP420G4HitCollection(GetName(), collectionName[0]);
0095 if (hcID < 0)
0096 hcID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
0097 HCE->AddHitsCollection(hcID, theHC);
0098
0099 tsID = -2;
0100
0101 primID = 0;
0102
0103
0104 }
0105
0106 bool FP420SD::ProcessHits(G4Step* aStep, G4TouchableHistory*) {
0107 if (aStep == nullptr) {
0108 return true;
0109 } else {
0110 GetStepInfo(aStep);
0111
0112
0113
0114 #ifdef debug
0115 LogDebug("FP420Sim") << "FP420SD : number of hits = " << theHC->entries() << std::endl;
0116 #endif
0117
0118 if (HitExists() == false && edeposit > 0. && theHC->entries() < 200) {
0119 CreateNewHit();
0120 return true;
0121 }
0122 }
0123 return true;
0124 }
0125
0126 void FP420SD::GetStepInfo(G4Step* aStep) {
0127 preStepPoint = aStep->GetPreStepPoint();
0128 postStepPoint = aStep->GetPostStepPoint();
0129 theTrack = aStep->GetTrack();
0130 hitPoint = preStepPoint->GetPosition();
0131 currentPV = preStepPoint->GetPhysicalVolume();
0132 hitPointExit = postStepPoint->GetPosition();
0133
0134 hitPointLocal = preStepPoint->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
0135 hitPointLocalExit = preStepPoint->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPointExit);
0136
0137 G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
0138 if (particleCode == emPDG || particleCode == epPDG || particleCode == gammaPDG) {
0139 edepositEM = getEnergyDeposit(aStep);
0140 edepositHAD = 0.;
0141 } else {
0142 edepositEM = 0.;
0143 edepositHAD = getEnergyDeposit(aStep);
0144 }
0145 edeposit = aStep->GetTotalEnergyDeposit();
0146 tSlice = (postStepPoint->GetGlobalTime()) / CLHEP::nanosecond;
0147 tSliceID = (int)tSlice;
0148 unitID = setDetUnitId(aStep);
0149 #ifdef debug
0150 LogDebug("FP420Sim") << "unitID=" << unitID << std::endl;
0151 #endif
0152 primaryID = theTrack->GetTrackID();
0153
0154 Pabs = aStep->GetPreStepPoint()->GetMomentum().mag() / CLHEP::GeV;
0155
0156 Tof = aStep->GetPostStepPoint()->GetGlobalTime() / CLHEP::nanosecond;
0157 Eloss = aStep->GetTotalEnergyDeposit() / CLHEP::GeV;
0158 ParticleType = theTrack->GetDefinition()->GetPDGEncoding();
0159 ThetaAtEntry = aStep->GetPreStepPoint()->GetPosition().theta() / CLHEP::deg;
0160 PhiAtEntry = aStep->GetPreStepPoint()->GetPosition().phi() / CLHEP::deg;
0161
0162 ParentId = theTrack->GetParentID();
0163 Vx = theTrack->GetVertexPosition().x();
0164 Vy = theTrack->GetVertexPosition().y();
0165 Vz = theTrack->GetVertexPosition().z();
0166 X = hitPoint.x();
0167 Y = hitPoint.y();
0168 Z = hitPoint.z();
0169 }
0170
0171 uint32_t FP420SD::setDetUnitId(const G4Step* aStep) {
0172 return (numberingScheme == nullptr ? 0 : numberingScheme->getUnitID(aStep));
0173 }
0174
0175 G4bool FP420SD::HitExists() {
0176 if (primaryID < 1) {
0177 edm::LogWarning("FP420Sim") << "***** FP420SD error: primaryID = " << primaryID << " maybe detector name changed";
0178 }
0179
0180
0181
0182 if (tSliceID == tsID && unitID == previousUnitID) {
0183
0184 UpdateHit();
0185 return true;
0186 }
0187
0188 if (primaryID != primID)
0189 ResetForNewPrimary();
0190
0191
0192
0193
0194 G4bool found = false;
0195
0196
0197 int nhits = theHC->entries();
0198 for (int j = 0; j < nhits && !found; j++) {
0199 FP420G4Hit* aPreviousHit = (*theHC)[j];
0200 if (aPreviousHit->getTrackID() == primaryID && aPreviousHit->getTimeSliceID() == tSliceID &&
0201 aPreviousHit->getUnitID() == unitID) {
0202
0203 currentHit = aPreviousHit;
0204 found = true;
0205 }
0206 }
0207
0208 if (found) {
0209
0210 UpdateHit();
0211 return true;
0212 } else {
0213 return false;
0214 }
0215 }
0216
0217 void FP420SD::ResetForNewPrimary() {
0218 entrancePoint = SetToLocal(hitPoint);
0219 exitPoint = SetToLocalExit(hitPointExit);
0220 incidentEnergy = preStepPoint->GetKineticEnergy();
0221 }
0222
0223 void FP420SD::StoreHit(FP420G4Hit* hit) {
0224
0225 if (hit == nullptr) {
0226 edm::LogWarning("FP420Sim") << "FP420SD: hit to be stored is NULL !!";
0227 return;
0228 }
0229
0230 theHC->insert(hit);
0231 }
0232
0233 void FP420SD::CreateNewHit() {
0234 #ifdef debug
0235
0236 LogDebug("FP420Sim") << "FP420SD CreateNewHit for"
0237 << " PV " << currentPV->GetName() << " PVid = " << currentPV->GetCopyNo() << " Unit " << unitID
0238 << std::endl;
0239 LogDebug("FP420Sim") << " primary " << primaryID << " time slice " << tSliceID << " For Track "
0240 << theTrack->GetTrackID() << " which is a " << theTrack->GetDefinition()->GetParticleName();
0241
0242 if (theTrack->GetTrackID() == 1) {
0243 LogDebug("FP420Sim") << " of energy " << theTrack->GetTotalEnergy();
0244 } else {
0245 LogDebug("FP420Sim") << " daughter of part. " << theTrack->GetParentID();
0246 }
0247
0248 LogDebug("FP420Sim") << " and created by ";
0249 if (theTrack->GetCreatorProcess() != NULL)
0250 LogDebug("FP420Sim") << theTrack->GetCreatorProcess()->GetProcessName();
0251 else
0252 LogDebug("FP420Sim") << "NO process";
0253 LogDebug("FP420Sim") << std::endl;
0254 #endif
0255
0256 currentHit = new FP420G4Hit;
0257 currentHit->setTrackID(primaryID);
0258 currentHit->setTimeSlice(tSlice);
0259 currentHit->setUnitID(unitID);
0260 currentHit->setIncidentEnergy(incidentEnergy);
0261
0262 currentHit->setPabs(Pabs);
0263 currentHit->setTof(Tof);
0264 currentHit->setEnergyLoss(Eloss);
0265 currentHit->setParticleType(ParticleType);
0266 currentHit->setThetaAtEntry(ThetaAtEntry);
0267 currentHit->setPhiAtEntry(PhiAtEntry);
0268
0269
0270 currentHit->setEntry(hitPoint);
0271
0272 currentHit->setEntryLocalP(hitPointLocal);
0273 currentHit->setExitLocalP(hitPointLocalExit);
0274
0275 currentHit->setParentId(ParentId);
0276 currentHit->setVx(Vx);
0277 currentHit->setVy(Vy);
0278 currentHit->setVz(Vz);
0279
0280 currentHit->setX(X);
0281 currentHit->setY(Y);
0282 currentHit->setZ(Z);
0283
0284
0285
0286 tsID = tSliceID;
0287 primID = primaryID;
0288 previousUnitID = unitID;
0289
0290 StoreHit(currentHit);
0291 }
0292
0293 void FP420SD::UpdateHit() {
0294
0295 if (Eloss > 0.) {
0296 currentHit->addEnergyDeposit(edepositEM, edepositHAD);
0297
0298 #ifdef debug
0299 LogDebug("FP420Sim") << "updateHit: add eloss " << Eloss << std::endl;
0300 LogDebug("FP420Sim") << "CurrentHit=" << currentHit << ", PostStepPoint=" << postStepPoint->GetPosition()
0301 << std::endl;
0302 #endif
0303
0304
0305 currentHit->addEnergyLoss(Eloss);
0306 }
0307
0308
0309 tsID = tSliceID;
0310 primID = primaryID;
0311 previousUnitID = unitID;
0312 }
0313
0314 G4ThreeVector FP420SD::SetToLocal(const G4ThreeVector& global) {
0315 const G4VTouchable* touch = preStepPoint->GetTouchable();
0316 theEntryPoint = touch->GetHistory()->GetTopTransform().TransformPoint(global);
0317 return theEntryPoint;
0318 }
0319
0320 G4ThreeVector FP420SD::SetToLocalExit(const G4ThreeVector& globalPoint) {
0321 const G4VTouchable* touch = postStepPoint->GetTouchable();
0322 theExitPoint = touch->GetHistory()->GetTopTransform().TransformPoint(globalPoint);
0323 return theExitPoint;
0324 }
0325
0326 void FP420SD::EndOfEvent(G4HCofThisEvent*) {
0327
0328
0329
0330
0331
0332
0333 int nhitsHPS240 = 0;
0334 int nhitsFP420 = 0;
0335 int nhits = theHC->entries();
0336 for (int j = 0; j < nhits; j++) {
0337 FP420G4Hit* aHit = (*theHC)[j];
0338 if ((fabs(aHit->getTof()) > 780. && fabs(aHit->getTof()) < 840.))
0339 ++nhitsHPS240;
0340 if ((fabs(aHit->getTof()) > 1380. && fabs(aHit->getTof()) < 1450.))
0341 ++nhitsFP420;
0342
0343 if ((fabs(aHit->getTof()) > 780. && fabs(aHit->getTof()) < 840. && nhitsHPS240 < 200.) ||
0344 (fabs(aHit->getTof()) > 1380. && fabs(aHit->getTof()) < 1450. && nhitsFP420 < 200.)) {
0345 #ifdef ddebug
0346
0347 LogDebug("FP420Sim") << "hit number" << j << "unit ID = " << aHit->getUnitID() << "\n";
0348 LogDebug("FP420Sim") << "entry z " << aHit->getEntry().z() << "\n";
0349 LogDebug("FP420Sim") << "entr theta " << aHit->getThetaAtEntry() << "\n";
0350 #endif
0351
0352
0353
0354
0355
0356 Local3DPoint locExitPoint(aHit->getExitLocalP().x(), aHit->getExitLocalP().y(), aHit->getExitLocalP().z());
0357 Local3DPoint locEntryPoint(aHit->getEntryLocalP().x(), aHit->getEntryLocalP().y(), aHit->getEntryLocalP().z());
0358
0359 slave->processHits(PSimHit(locEntryPoint,
0360 locExitPoint,
0361 aHit->getPabs(),
0362 aHit->getTof(),
0363 aHit->getEnergyLoss(),
0364 aHit->getParticleType(),
0365 aHit->getUnitID(),
0366 aHit->getTrackID(),
0367 aHit->getThetaAtEntry(),
0368 aHit->getPhiAtEntry()));
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 }
0395 }
0396
0397 Summarize();
0398 }
0399
0400 void FP420SD::Summarize() {}
0401
0402 void FP420SD::clear() {}
0403
0404 void FP420SD::DrawAll() {}
0405
0406 void FP420SD::PrintAll() {
0407 LogDebug("FP420Sim") << "FP420SD: Collection " << theHC->GetName() << "\n";
0408 theHC->PrintAllHits();
0409 }
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419 void FP420SD::fillHits(edm::PSimHitContainer& cc, const std::string& hname) {
0420 if (slave->name() == hname) {
0421 cc = slave->hits();
0422 }
0423 }
0424
0425 void FP420SD::update(const BeginOfEvent* i) {
0426 LogDebug("ForwardSim") << " Dispatched BeginOfEvent for " << GetName() << " !";
0427 clearHits();
0428 eventno = (*i)()->GetEventID();
0429 }
0430
0431 void FP420SD::update(const BeginOfRun*) {
0432 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
0433 G4String particleName;
0434 emPDG = theParticleTable->FindParticle(particleName = "e-")->GetPDGEncoding();
0435 epPDG = theParticleTable->FindParticle(particleName = "e+")->GetPDGEncoding();
0436 gammaPDG = theParticleTable->FindParticle(particleName = "gamma")->GetPDGEncoding();
0437 }
0438
0439 void FP420SD::update(const ::EndOfEvent*) {}
0440
0441 void FP420SD::clearHits() {
0442
0443 slave->Initialize();
0444 }