11 #include "G4EventManager.hh"
12 #include "G4SDManager.hh"
15 #include "G4VProcess.hh"
16 #include "G4GFlashSpot.hh"
17 #include "G4ParticleTable.hh"
19 #include "G4SystemOfUnits.hh"
20 #include "G4PhysicalConstants.hh"
27 int tSlice,
bool ignoreTkID) :
29 G4VGFlashSensitiveDetector(), theTrack(0), preStepPoint(0), eminHit(0),
30 eminHitD(0), m_trackManager(manager), currentHit(0), runInit(
false),
31 timeSlice(tSlice), ignoreTrackID(ignoreTkID), hcID(-1), theHC(0),
41 std::vector<double> eminHits = m_CaloSD.
getParameter<std::vector<double> >(
"EminHits");
42 std::vector<double> tmaxHits = m_CaloSD.
getParameter<std::vector<double> >(
"TmaxHits");
43 std::vector<std::string> hcn = m_CaloSD.
getParameter<std::vector<std::string> >(
"HCNames");
44 std::vector<int> useResMap = m_CaloSD.
getParameter<std::vector<int> >(
"UseResponseTables");
45 std::vector<double> eminHitX = m_CaloSD.
getParameter<std::vector<double> >(
"EminHitsDepth");
54 double beamZ = m_CaloSD.
getParameter<
double>(
"BeamPosition")*cm;
57 SetVerboseLevel(verbn);
58 for (
unsigned int k=0;
k<hcn.size(); ++
k) {
59 if (name == (G4String)(hcn[
k])) {
60 if (
k < eminHits.size())
eminHit = eminHits[
k]*MeV;
61 if (
k < eminHitX.size())
eminHitD= eminHitX[
k]*MeV;
62 if (
k < tmaxHits.size()) tmaxHit = tmaxHits[
k]*ns;
68 LogDebug(
"CaloSim") <<
"***************************************************"
72 <<
"* Constructing a CaloSD with name " << GetName()
76 <<
"***************************************************";
90 std::vector<std::string> lvNames = clg.
logicalNames(name);
92 for (std::vector<std::string>::iterator it=lvNames.begin(); it !=lvNames.end(); ++it) {
95 LogDebug(
"CaloSim") <<
"CaloSD : Assigns SD to LV " << (*it);
99 edm::LogInfo(
"CaloSim") <<
"CaloSD: Minimum energy of track for saving it "
100 << energyCut/GeV <<
" GeV" <<
"\n"
101 <<
" Use of HitID Map " << useMap <<
"\n"
102 <<
" Check last " << checkHits
103 <<
" before saving the hit\n"
104 <<
" Correct TOF globally by " << correctT
105 <<
" ns (Flag =" << corrTOFBeam <<
")\n"
106 <<
" Save hits recorded before " << tmaxHit
107 <<
" ns and if energy is above " <<
eminHit/MeV
108 <<
" MeV (for depth 0) or " <<
eminHitD/MeV
109 <<
" MeV (for nonzero depths); Time Slice Unit "
137 theTrack =
const_cast<G4Track *
>(aSpot->GetOriginatorTrack()->GetPrimaryTrack());
138 G4int particleCode =
theTrack->GetDefinition()->GetPDGEncoding();
140 if (particleCode ==
emPDG ||
141 particleCode ==
epPDG ||
143 edepositEM = aSpot->GetEnergySpot()->GetEnergy();
151 G4Step * fFakeStep =
new G4Step();
153 G4StepPoint * fFakePostStepPoint = fFakeStep->GetPostStepPoint();
155 fFakePostStepPoint->SetPosition(aSpot->GetPosition());
157 G4TouchableHandle fTouchableHandle = aSpot->GetTouchableHandle();
159 fFakeStep->SetTotalEnergyDeposit(aSpot->GetEnergySpot()->GetEnergy());
164 uint16_t depth =
getDepth(fFakeStep);
169 LogDebug(
"CaloSim") <<
"CaloSD:: GetSpotInfo for"
171 << std::dec <<
" Edeposit = " <<
edepositEM <<
" "
178 posGlobal = aSpot->GetEnergySpot()->GetPosition();
186 LogDebug(
"CaloSim") <<
"CaloSD: Incident energy "
204 return aStep->GetTotalEnergyDeposit();
211 edm::LogInfo(
"CaloSim") <<
"CaloSD : Initialize called for " << GetName();
228 edm::LogInfo(
"CaloSim") <<
"CaloSD: EndofEvent entered with " <<
theHC->entries()
242 theHC->PrintAllHits();
255 double time = (aStep->GetPostStepPoint()->GetGlobalTime())/nanosecond;
260 bool flag = (unitID > 0);
264 G4TouchableHistory* touch =(G4TouchableHistory*)(
theTrack->GetTouchable());
265 LogDebug(
"CaloSim") <<
"CaloSD:: GetStepInfo for"
266 <<
" PV " << touch->GetVolume(0)->GetName()
267 <<
" PVid = " << touch->GetReplicaNumber(0)
268 <<
" MVid = " << touch->GetReplicaNumber(1)
272 G4TouchableHistory* touch =(G4TouchableHistory*)(
theTrack->GetTouchable());
273 LogDebug(
"CaloSim") <<
"CaloSD:: GetStepInfo for"
274 <<
" PV " << touch->GetVolume(0)->GetName()
275 <<
" PVid = " << touch->GetReplicaNumber(0)
276 <<
" MVid = " << touch->GetReplicaNumber(1)
277 <<
" Unit " << std::hex << unitID << std::dec
282 G4int particleCode =
theTrack->GetDefinition()->GetPDGEncoding();
283 if (particleCode ==
emPDG ||
284 particleCode ==
epPDG ||
298 G4ThreeVector localPoint = touch->GetHistory()->GetTopTransform().TransformPoint(global);
305 G4ThreeVector globalPoint = touch->GetHistory()->GetTopTransform().Inverse().TransformPoint(local);
315 <<
" maybe detector name changed";
335 std::map<CaloHitID,CaloG4Hit*>::const_iterator it =
hitMap.find(
currentID);
343 int maxhit=
theHC->entries()-1;
345 for (
int j=maxhit;
j>minhit&&!
found; --
j) {
365 LogDebug(
"CaloSim") <<
"CaloSD::CreateNewHit for"
371 <<
" For Track " <<
theTrack->GetTrackID()
372 <<
" which is a " <<
theTrack->GetDefinition()->GetParticleName()
373 <<
" of energy " <<
theTrack->GetKineticEnergy()/GeV
374 <<
" " <<
theTrack->GetMomentum().mag()/GeV
375 <<
" daughter of part. " <<
theTrack->GetParentID()
376 <<
" and created by " ;
381 LogDebug(
"CaloSim") <<
"NO process";
405 etrack=
theTrack->GetKineticEnergy();
421 LogDebug(
"CaloSim") <<
"CaloSD : TrackwithHistory pointer for "
429 LogDebug(
"CaloSim") <<
"CaloSD: set save the track "
459 LogDebug(
"CaloSim") <<
"CaloSD: Incident energy " << incidentEnergy/GeV
467 double charge = aStep->GetPreStepPoint()->GetCharge();
469 if (charge != 0. && aStep->GetStepLength() > 0) {
470 G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
471 double density = mat->GetDensity();
472 double dedx = aStep->GetTotalEnergyDeposit()/aStep->GetStepLength();
473 double rkb = birk1/density;
474 double c = birk2*rkb*rkb;
475 if (
std::abs(charge) >= 2.) rkb /= birk3;
476 weight = 1./(1.+rkb*dedx+c*dedx*dedx);
478 LogDebug(
"CaloSim") <<
"CaloSD::getAttenuation in " << mat->GetName()
479 <<
" Charge " << charge <<
" dE/dx " << dedx
480 <<
" Birk Const " << rkb <<
", " << c <<
" Weight = "
481 << weight <<
" dE " << aStep->GetTotalEnergyDeposit();
488 G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
489 G4String particleName;
490 emPDG = theParticleTable->FindParticle(particleName=
"e-")->GetPDGEncoding();
491 epPDG = theParticleTable->FindParticle(particleName=
"e+")->GetPDGEncoding();
492 gammaPDG = theParticleTable->FindParticle(particleName=
"gamma")->GetPDGEncoding();
494 LogDebug(
"CaloSim") <<
"CaloSD: Particle code for e- = " <<
emPDG
503 LogDebug(
"CaloSim") <<
"CaloSD: Dispatched BeginOfEvent for " << GetName()
510 int id = (*trk)()->GetTrackID();
512 int lastTrackID = -1;
514 if (
id == lastTrackID) {
516 if (trksForThisEvent !=
NULL) {
517 int it = (int)(trksForThisEvent->size()) - 1;
520 if (trkH->
trackID() == (
unsigned int)(
id))
tkMap[
id] = trkH;
522 LogDebug(
"CaloSim") <<
"CaloSD: get track " << it <<
" from "
523 <<
"Container of size " << trksForThisEvent->size()
524 <<
" with ID " << trkH->
trackID();
526 LogDebug(
"CaloSim") <<
"CaloSD: get track " << it <<
" from "
527 <<
"Container of size " << trksForThisEvent->size()
536 int count = 0, wrong = 0;
541 for (
int i=0;
i<
theHC->entries(); ++
i) {
547 edm::LogInfo(
"CaloSim") <<
"CaloSD: " << GetName() <<
" store " << count
548 <<
" hits recorded with " << wrong
549 <<
" track IDs not given properly and "
550 <<
totalHits-count <<
" hits not passing cuts";
564 LogDebug(
"CaloSim") <<
"CaloSD: Clears hit vector for " << GetName() <<
" " <<
slave;
568 LogDebug(
"CaloSim") <<
"CaloSD: Initialises slave SD for " << GetName();
581 LogDebug(
"CaloSim") <<
"CaloSD: hit update from track Id on Calo Surface "
585 primaryID = aTrack->GetTrackID();
587 edm::LogWarning(
"CaloSim") <<
"CaloSD: Problem with primaryID **** set by "
588 <<
"force to TkID **** " << primaryID <<
" in "
589 <<
preStepPoint->GetTouchable()->GetVolume(0)->GetName();
601 LogDebug(
"CaloSim") <<
"Depth " << hit->
getDepth() <<
" Emin = " << emin <<
" ("
645 <<
" changed to " << tkID <<
" by SimTrackManager"
653 LogDebug(
"CaloSim") <<
"CaloSD: Store Hit at " << std::hex
655 << aHit->
getDepth() <<
" due to " << tkID
656 <<
" in time " << time <<
" of energy "
657 << aHit->
getEM()/GeV <<
" GeV (EM) and "
658 << aHit->
getHadr()/GeV <<
" GeV (Hadr)";
668 if ( trkInfo->
isPrimary() ) primary = (*trk)()->GetTrackID();
672 <<
" primary ID = " << primary
678 if (primary > 0 && primary != primAncestor) {
679 primAncestor = primary;
689 std::vector<CaloG4Hit*>* theCollection =
theHC->GetVector();
692 LogDebug(
"CaloSim") <<
"CaloSD: collection before merging, size = " <<
theHC->entries();
700 hitvec.swap(*theCollection);
703 LogDebug(
"CaloSim") <<
"CaloSD::cleanHitCollection: sort hits in buffer "
705 for (
unsigned int i = 0;
i<
hitvec.size(); ++
i)
710 for (i=cleanIndex; i<hitvec.size(); ++
i) {
713 for (j = i+1; j <hitvec.size() &&
equal(hitvec[i], hitvec[j]); ++
j) {
716 (*hitvec[
i]).addEnergyDeposit(*hitvec[j]);
717 (*hitvec[
j]).setEM(0.);
718 (*hitvec[
j]).setHadr(0.);
724 LogDebug(
"CaloSim") <<
"CaloSD: cleanHitCollection merge the hits in buffer ";
725 for (
unsigned int i = 0; i<hitvec.size(); ++
i)
728 for (
unsigned int i = cleanIndex; i < cleanIndex+
selIndex.size(); ++
i ) {
731 hitvec.resize(cleanIndex+
selIndex.size());
733 LogDebug(
"CaloSim") <<
"CaloSD::cleanHitCollection: remove the merged hits in buffer,"
734 <<
" new size = " << hitvec.size();
735 for (
unsigned int i = 0; i<hitvec.size(); ++
i)
738 hitvec.swap(*theCollection);
739 std::vector<CaloG4Hit*>().
swap(hitvec);
745 LogDebug(
"CaloSim") <<
"CaloSD: collection after merging, size = " <<
theHC->entries();
751 LogDebug(
"CaloSim") <<
"CaloSD: Size of reusehit after merge = " <<
reusehit.size();
756 for (
unsigned int i =
cleanIndex;
i<theCollection->size(); ++
i) {
765 LogDebug(
"CaloSim") <<
"CaloSD: dropped CaloG4Hit " <<
" " << *aHit;
770 reusehit.push_back((*theCollection)[i]);
778 LogDebug(
"CaloSim") <<
"CaloSD: Size of reusehit after selection = " <<
reusehit.size()
779 <<
" Number of added hit = " << addhit;
784 for (
int ii = addhit-1;
ii>=0; --
ii) {
798 LogDebug(
"CaloSim") <<
"CaloSD: hit collection after selection, size = "
800 theHC->PrintAllHits();
void swap(ora::Record &rh, ora::Record &lh)
virtual bool processHits(uint32_t, double, double, double, int, uint16_t depth=0)
T getParameter(std::string const &) const
virtual void Initialize()
T getUntrackedParameter(std::string const &, T const &) const
virtual uint32_t setDetUnitId(G4Step *step)=0
std::vector< PCaloHit > PCaloHitContainer
std::vector< std::string > logicalNames(std::string &readoutName)
void updateHit(CaloG4Hit *)
virtual void Initialize(G4HCofThisEvent *HCE)
void setIncidentEnergy(double e)
virtual void EndOfEvent(G4HCofThisEvent *eventHC)
void setEntryLocal(double x, double y, double z)
uint16_t getDepth() const
virtual int getTrackID(G4Track *)
void fillHits(edm::PCaloHitContainer &, std::string n)
type of data representation of DDCompactView
std::vector< CaloG4Hit * > reusehit
bool equal(const T &first, const T &second)
void cleanHitCollection()
double getWeight(int genPID, double genP)
CaloSD(G4String aSDname, const DDCompactView &cpv, SensitiveDetectorCatalog &clg, edm::ParameterSet const &p, const SimTrackManager *, int tSlice=1, bool ignoreTkID=false)
void addEnergyDeposit(double em, double hd)
const TrackContainer * trackContainer() const
void resetForNewPrimary(const G4ThreeVector &, double)
std::string const collectionName[nCollections]
std::vector< TrackWithHistory * > TrackContainer
unsigned int trackID() const
bool trackExists(unsigned int i) const
virtual void ReserveMemory(unsigned int size)
virtual void update(const BeginOfRun *)
This routine will be called when the appropriate signal arrives.
void setID(uint32_t i, double d, int j, uint16_t k=0)
Abs< T >::type abs(const T &t)
std::vector< CaloG4Hit * > hitvec
G4ThreeVector setToGlobal(const G4ThreeVector &, const G4VTouchable *)
double getAttenuation(G4Step *aStep, double birk1, double birk2, double birk3)
int giveMotherNeeded(int i) const
std::vector< unsigned int > selIndex
CaloMeanResponse * meanResponse
unsigned int offset(bool)
void NaNTrap(G4Step *step)
void storeHit(CaloG4Hit *)
virtual bool filterHit(CaloG4Hit *, double)
virtual G4bool getStepInfo(G4Step *aStep)
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
G4StepPoint * preStepPoint
virtual bool ProcessHits(G4Step *step, G4TouchableHistory *tHistory)
const math::XYZVectorD & momentum() const
CSCCFEBTimeSlice const *const timeSlice(T const &data, int nCFEB, int nSample)
virtual void AssignSD(std::string &vname)
std::map< CaloHitID, CaloG4Hit * > hitMap
CaloG4HitCollection * theHC
double getResponseWt(G4Track *)
void setPosition(double x, double y, double z)
void setEntry(double x, double y, double z)
G4THitsCollection< CaloG4Hit > CaloG4HitCollection
double getTimeSlice() const
std::map< int, TrackWithHistory * > tkMap
const SimTrackManager * m_trackManager
volatile std::atomic< bool > shutdown_flag false
uint32_t getUnitID() const
bool saveHit(CaloG4Hit *)
CaloG4Hit * createNewHit()
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
virtual uint16_t getDepth(G4Step *)
G4ThreeVector entrancePoint
G4ThreeVector entranceLocal
double getEnergyDeposit() const
virtual double getEnergyDeposit(G4Step *step)
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *)