43 #include "G4RunManager.hh" 44 #include "G4SDManager.hh" 48 #include "G4PrimaryVertex.hh" 49 #include "G4VProcess.hh" 50 #include "G4HCofThisEvent.hh" 51 #include "G4UserEventAction.hh" 53 #include <CLHEP/Random/Randomize.h> 54 #include <CLHEP/Units/SystemOfUnits.h> 55 #include <CLHEP/Units/PhysicalConstants.h> 56 #include <CLHEP/Units/GlobalSystemOfUnits.h> 57 #include <CLHEP/Units/GlobalPhysicalConstants.h> 66 #include "TLorentzVector.h" 67 #include "TUnixSystem.h" 83 typedef std::vector<std::vector<std::vector<std::vector<CastorShowerEvent> > > >
SLBin3D;
89 public Observer<const BeginOfEvent*>,
159 void GetKinematics(G4PrimaryParticle*,
double&
px,
double&
py,
double& pz,
double& pInit,
double&
eta,
double&
phi);
162 std::vector<G4PrimaryParticle*>
GetPrimary(
const G4Event*);
188 DeActivatePhysicsProcess(
false),
226 edm::LogVerbatim(
"HcalSim") <<
"============================================================================";
227 edm::LogVerbatim(
"HcalSim") <<
"CastorShowerLibraryMaker:: Initialized as observer";
236 edm::LogVerbatim(
"HcalSim") <<
"============================================================================\n";
269 showerholder.
nEvtInBinEta.assign(nBinsE, std::vector<int>(0));
271 for (
int i = 0;
i < nBinsE;
i++) {
294 edm::LogVerbatim(
"HcalSim") <<
" CastorShowerLibraryMaker::Starting new job ";
301 edm::LogVerbatim(
"HcalSim") <<
"CastorShowerLibraryMaker: output event root file created";
304 theFile =
new TFile(eventfilename,
"RECREATE");
305 theTree =
new TTree(
"CastorCherenkovPhotons",
"Cherenkov Photons");
314 theTree->Branch(
"emShowerLibInfo.",
"CastorShowerLibraryInfo", &
emInfo, bsize,
split);
381 G4EventManager* e_mgr = G4EventManager::GetEventManager();
389 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
390 G4PrimaryParticle* thePrim =
thePrims.at(
i);
396 SLType =
"Electromagnetic";
401 double px = 0.,
py = 0., pz = 0., pInit = 0.,
eta = 0.,
phi = 0.;
407 edm::LogVerbatim(
"HcalSim") <<
"\n========================================================================" 408 <<
"\nBeginOfEvent: E : " << pInit <<
"\t bin : " <<
ebin 409 <<
"\n Eta : " <<
eta <<
"\t bin : " <<
etabin 410 <<
"\n Phi : " <<
phi <<
"\t bin : " <<
phibin 411 <<
"\n========================================================================";
437 <<
"Event not accepted for ebin=" <<
ebin <<
",etabin=" <<
etabin <<
",phibin=" <<
phibin;
445 if (NAccepted == 0) {
446 const_cast<G4Event*
>((*evt)())->SetEventAborted();
447 const_cast<G4Event*
>((*evt)())->KeepTheEvent((G4bool)
false);
448 e_mgr->AbortCurrentEvent();
457 static thread_local
int CurrentPrimary = 0;
458 G4Track* trk = aStep->GetTrack();
460 if (trk->GetCurrentStepNumber() == 1) {
461 if (trk->GetParentID() == 0) {
462 CurrentPrimary = (
int)trk->GetDynamicParticle()->GetPDGcode();
463 if (CurrentPrimary == 0)
464 SimG4Exception(
"CastorShowerLibraryMaker::update(G4Step) -> Primary particle undefined");
468 G4ProcessManager* p_mgr = trk->GetDefinition()->GetProcessManager();
469 G4ProcessVector* pvec = p_mgr->GetProcessList();
470 pvec_size = pvec->size();
471 for (
int i = 0;
i < pvec_size;
i++) {
472 G4VProcess*
proc = (*pvec)(
i);
473 if (
proc->GetProcessName() !=
"Transportation" &&
proc->GetProcessName() !=
"Decay") {
475 p_mgr->SetProcessActivation(
proc,
false);
482 double t =
std::abs((
pos.z() - trk->GetPosition().z())) / trk->GetVelocity();
483 double r = (
pos.z() - trk->GetPosition().z()) / trk->GetMomentum().cosTheta();
484 pos.setX(
r *
sin(trk->GetMomentum().theta()) *
cos(trk->GetMomentum().phi()) + trk->GetPosition().x());
485 pos.setY(
r *
sin(trk->GetMomentum().theta()) *
sin(trk->GetMomentum().phi()) + trk->GetPosition().y());
486 trk->SetPosition(
pos);
487 trk->SetGlobalTime(trk->GetGlobalTime() +
t);
488 trk->AddTrackLength(
r);
490 edm::LogVerbatim(
"HcalSim") <<
"CastorShowerLibraryMaker::update(G4Step) -> Killing spurious track";
491 trk->SetTrackStatus(fKillTrackAndSecondaries);
497 std::string CurVolume = trk->GetVolume()->GetName();
502 CurVolume ==
"CAST")) {
507 G4ProcessManager* p_mgr = trk->GetDefinition()->GetProcessManager();
508 G4ProcessVector* pvec = p_mgr->GetProcessList();
509 pvec_size = pvec->size();
510 for (
int i = 0;
i < pvec_size;
i++) {
511 G4VProcess*
proc = (*pvec)(
i);
512 if (
proc->GetProcessName() !=
"Transportation" &&
proc->GetProcessName() !=
"Decay") {
514 p_mgr->SetProcessActivation(
proc,
true);
520 if (trk->GetMomentum().phi() >
MaxPhi || trk->GetMomentum().eta() >
MaxEta) {
521 trk->SetTrackStatus(fKillTrackAndSecondaries);
531 if (CurrentPrimary != 0 && trk->GetParentID() == 0 && !
InsideCastor) {
534 double pre_phi = aStep->GetPreStepPoint()->GetMomentum().phi();
535 double cur_phi = trk->GetMomentum().phi();
536 if (pre_phi != cur_phi) {
537 edm::LogVerbatim(
"HcalSim") <<
"Primary track phi : " << pre_phi <<
" changed in current step: " << cur_phi
539 const G4VProcess*
proc = aStep->GetPreStepPoint()->GetProcessDefinedStep();
561 if ((*evt)()->IsAborted()) {
562 edm::LogVerbatim(
"HcalSim") <<
"\n========================================================================" 563 <<
"\nEndOfEvent: EVENT ABORTED" 564 <<
"\n========================================================================";
576 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"No valid primary particle found. Skipping event";
580 G4HCofThisEvent* allHC = (*evt)()->GetHCofThisEvent();
581 int CAFIid = G4SDManager::GetSDMpointer()->GetCollectionID(
"CastorFI");
584 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
" update(*evt) --> accessed all HC ";
585 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"Found " << theCAFI->entries() <<
" hits in G4HitCollection";
586 if (theCAFI->entries() == 0) {
592 int NEvtAccepted = 0;
594 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
595 G4PrimaryParticle* thePrim =
thePrims.at(
i);
597 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"nullptr Pointer to the primary";
607 SLType =
"Electromagnetic";
612 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n Primary (thePrim) trackID is " << thePrim->GetTrackID() <<
"\n";
615 double px = 0.,
py = 0., pz = 0., pInit = 0.,
eta = 0.,
phi = 0.;
620 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"Primary did not hit CASTOR";
630 <<
"Event not accepted for ebin=" <<
ebin <<
",etabin=" <<
etabin <<
",phibin=" <<
phibin <<
"(" << pInit
631 <<
"," <<
eta <<
"," <<
phi <<
")";
639 <<
"\n CastorShowerLibraryMaker::update(EndOfEvent * evt) - event #" << (*evt)()->GetEventID();
666 NHitInEvent += shower->
getNhit();
673 int thecafi_entries = theCAFI->entries();
674 if (NEvtAccepted ==
int(
thePrims.size()) && thecafi_entries != NHitInEvent) {
675 edm::LogWarning(
"HcalSim") <<
"WARNING: Inconsistent Number of Hits -> Hits in collection: " << theCAFI->entries()
676 <<
" Hits in the showers: " << NHitInEvent;
677 double miss_energy = 0;
678 double tot_energy = 0;
680 if (miss_energy > 0) {
682 <<
" for an incident energy: " << tot_energy;
712 unsigned int ibine, ibineta, ibinphi, ievt;
713 unsigned int jbine, jbineta, jbinphi, jevt;
715 ibine = ibineta = ibinphi = ievt = jbine = jbineta = jbinphi = jevt = 0;
720 int maxEvtInTree =
std::max(nEMevt, nHadevt);
725 while (nEvtInTree < maxEvtInTree) {
766 if (nEvtInTree == 1) {
767 theTree->SetBranchStatus(
"emShowerLibInfo.",
false);
768 theTree->SetBranchStatus(
"hadShowerLibInfo.",
false);
773 throw SimG4Exception(
"\n\nNumber of needed trigger events reached in CastorShowerLibraryMaker\n\n");
781 theTree->Write(
"", TObject::kOverwrite);
782 edm::LogVerbatim(
"HcalSim") <<
"CastorShowerLibraryMaker: Ntuple event written";
784 edm::LogVerbatim(
"HcalSim") <<
"CastorShowerLibraryMaker: Event file closed";
798 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nFindEnergyBin can be called only after BeginOfEvent\n\n";
799 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
802 if (
energy >= SLenergies.back())
803 return SLenergies.size() - 1;
806 for (;
i < SLenergies.size() - 1;
i++)
811 if (
energy >= SLenergies.at(
i))
822 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nFindEtaBin can be called only after BeginOfEvent\n\n";
823 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
826 if (
eta >= SLetas.back())
827 return SLetas.size() - 1;
829 for (;
i < SLetas.size() - 1;
i++)
830 if (
eta >= SLetas.at(
i) &&
eta < SLetas.at(
i + 1))
833 if (
eta >= SLetas.at(
i))
846 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nFindPhiBin can be called only after BeginOfEvent\n\n";
847 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
850 if (
phi >= SLphis.back())
851 return SLphis.size() - 1;
853 for (;
i < SLphis.size() - 1;
i++)
854 if (
phi >= SLphis.at(
i) &&
phi < SLphis.at(
i + 1))
857 if (
phi >= SLphis.at(
i))
865 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nIsSLReady must be called when a new event starts.\n\n";
866 throw SimG4Exception(
"\n\nNOT nullptr Pointer to the shower library.\n\n");
891 int thePrim,
double&
px,
double&
py,
double& pz,
double& pInit,
double&
eta,
double&
phi) {
902 double costheta = pz / pInit;
909 G4PrimaryParticle* thePrim,
double&
px,
double&
py,
double& pz,
double& pInit,
double&
eta,
double&
phi) {
911 if (thePrim ==
nullptr)
913 px = thePrim->GetMomentum().x() / GeV;
914 py = thePrim->GetMomentum().y() / GeV;
915 pz = thePrim->GetMomentum().z() / GeV;
916 pInit = thePrim->GetMomentum().mag() / GeV;
920 double costheta = pz / pInit;
924 phi = thePrim->GetMomentum().phi();
930 std::vector<G4PrimaryParticle*>
thePrims;
931 G4PrimaryParticle* thePrim =
nullptr;
932 G4int nvertex = evt->GetNumberOfPrimaryVertex();
933 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"Event has " << nvertex <<
" vertex";
935 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"CastorShowerLibraryMaker::GetPrimary ERROR: no vertex";
939 for (
int i = 0;
i < nvertex;
i++) {
940 G4PrimaryVertex* avertex = evt->GetPrimaryVertex(
i);
941 if (avertex ==
nullptr) {
943 <<
"CastorShowerLibraryMaker::GetPrimary ERROR: pointer to vertex = 0";
946 unsigned int npart = avertex->GetNumberOfParticle();
949 for (
unsigned int j = 0;
j <
npart;
j++) {
953 thePrim = avertex->GetPrimary(trackID);
966 edm::LogVerbatim(
"CastorShowerLibraryInfo") <<
"nullptr shower pointer. Printing both";
980 std::ostringstream st1;
984 for (
int i = 0;
i < nBinsE;
i++) {
985 std::ostringstream st1;
986 st1 <<
"E bin " << std::setw(6) << SLenergies.at(
i) <<
" : ";
998 std::ostringstream st2;
1009 std::ostringstream st2;
1016 edm::LogVerbatim(
"CastorShowerLibraryMaker::SLacceptEvent:") <<
"Error. nullptr pointer to CastorShowerEvent";
1036 unsigned int volumeID = 0;
1037 double en_in_fi = 0.;
1040 int nentries = theCAFI->entries();
1050 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"Error. nullptr pointer to CastorShowerEvent";
1060 for (
int ihit = 0; ihit < nentries; ihit++) {
1065 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"Skipping hit from trackID " << hit_particleID;
1072 int zside, sector, zmodule;
1077 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n side , sector , module = " <<
zside <<
" , " << sector
1078 <<
" , " << zmodule <<
"\n nphotons = " << hitEnergy;
1082 <<
"\n packIndex = " << theCastorNumScheme->
packIndex(
zside, sector, zmodule);
1086 <<
"\n nentries = " << nentries <<
"\n time[" << ihit <<
"] = " <<
time <<
"\n trackID[" << ihit
1087 <<
"] = " << aHit->
getTrackID() <<
"\n volumeID[" << ihit <<
"] = " << volumeID <<
"\n nphotons[" << ihit
1088 <<
"] = " << hitEnergy <<
"\n side, sector, module = " <<
zside <<
", " << sector <<
", " << zmodule
1089 <<
"\n packIndex " << theCastorNumScheme->
packIndex(
zside, sector, zmodule) <<
"\n X,Y,Z = " <<
entry.x()
1104 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"No hits found for this track (trackID=" << ipart <<
").";
1105 if (theCastorNumScheme)
1106 delete theCastorNumScheme;
1112 if (theCastorNumScheme)
1113 delete theCastorNumScheme;
1118 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinE can be called only after BeginOfEvent\n\n";
1119 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1126 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinEta can be called only after BeginOfEvent\n\n";
1127 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1134 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinPhi can be called only after BeginOfEvent\n\n";
1135 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1141 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nSLisEBinFilled can be called only after BeginOfEvent\n\n";
1142 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1150 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nSLisEtaBinFilled can be called only after BeginOfEvent\n\n";
1151 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1159 edm::LogVerbatim(
"CastorShowerLibraryMaker") <<
"\n\nSLisPhiBinFilled can be called only after BeginOfEvent\n\n";
1160 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1167 const G4TrackVector* p_sec = aStep->GetSecondary();
1168 for (
int i = 0;
i <
int(p_sec->size());
i++) {
1169 edm::LogVerbatim(
"HcalSim") <<
"Killing track ID " << p_sec->at(
i)->GetTrackID()
1170 <<
" and its secondaries Produced by Process " 1171 << p_sec->at(
i)->GetCreatorProcess()->GetProcessName() <<
" in the volume " 1172 << aStep->GetTrack()->GetVolume()->GetName();
1173 p_sec->at(
i)->SetTrackStatus(fKillTrackAndSecondaries);
1181 int nhits = theCAFI->entries();
1182 for (
int ihit = 0; ihit <
nhits; ihit++) {
1183 int id = (*theCAFI)[ihit]->getTrackID();
1184 tot_energy += (*theCAFI)[ihit]->getEnergyDeposit();
1186 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
1191 if (hit_prim == 0) {
1192 edm::LogVerbatim(
"HcalSim") <<
"Track ID " <<
id <<
" produced a hit which is not associated with a primary.";
1193 miss_energy += (*theCAFI)[ihit]->getEnergyDeposit();
std::string eventNtFileName
std::vector< double > SLEtaBins
void Clear(Option_t *option="") override
Log< level::Info, true > LogVerbatim
void setNBins(unsigned int n)
#define DEFINE_SIMWATCHER(type)
T getParameter(std::string const &) const
bool DeActivatePhysicsProcess
void setPrimEta(float eta)
int & SLnEvtInBinE(int ebin)
void setDetID(unsigned int id)
CastorShowerEvent * hadShower
std::vector< double > SLPhiBins
int & SLnEvtInBinEta(int ebin, int etabin)
void setPrimPhi(float phi)
std::vector< G4PrimaryParticle * > thePrims
CastorShowerLibraryInfo SLInfo
Sin< T >::type sin(const T &t)
bool FillShowerEvent(CaloG4HitCollection *, CastorShowerEvent *, int)
std::map< int, G4ThreeVector > PrimaryPosition
void KillSecondaries(const G4Step *step)
void InitSLHolder(ShowerLib &)
void printSLstatus(int, int, int)
std::vector< std::vector< std::vector< std::vector< CastorShowerEvent > > > > SLBin3D
bool SLacceptEvent(int, int, int)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
bool SLisEtaBinFilled(int ebin, int etabin)
static void unpackIndex(const uint32_t &idx, int &z, int §or, int &zmodule)
void setNEvtPerBin(unsigned int n)
std::map< int, std::set< int > > MapOfSecondaries
std::vector< G4PrimaryParticle * > GetPrimary(const G4Event *)
bool SLisEBinFilled(int ebin)
CastorShowerLibraryInfo * hadInfo
std::vector< int > nEvtInBinE
math::XYZPoint getPosition() const
math::XYZPoint getEntry() const
int FindEnergyBin(double e)
~CastorShowerLibraryMaker() override
Cos< T >::type cos(const T &t)
Tan< T >::type tan(const T &t)
Abs< T >::type abs(const T &t)
std::vector< std::vector< std::vector< int > > > nEvtInBinPhi
unsigned int nEvtPerBinPhi
CastorShowerLibraryInfo * emInfo
CastorShowerLibraryMaker(const edm::ParameterSet &p)
def split(sequence, size)
void GetMissingEnergy(CaloG4HitCollection *, double &, double &)
void GetKinematics(G4PrimaryParticle *, double &px, double &py, double &pz, double &pInit, double &eta, double &phi)
int & SLnEvtInBinPhi(int ebin, int etabin, int phibin)
XYZPointD XYZPoint
point in space with cartesian internal representation
std::vector< std::vector< int > > nEvtInBinEta
double getEnergyDeposit() const
caConstants::TupleMultiplicity const CAHitNtupletGeneratorKernelsGPU::HitToTuple const cms::cuda::AtomicPairCounter GPUCACell const *__restrict__ uint32_t const *__restrict__ gpuPixelDoublets::CellNeighborsVector const gpuPixelDoublets::CellTracksVector const GPUCACell::OuterHitOfCell const int32_t nHits
uint32_t getUnitID() const
int FindPhiBin(double phi)
void setNEvts(unsigned int n)
unsigned int nEvtPerBinEta
G4THitsCollection< CaloG4Hit > CaloG4HitCollection
static int position[264][3]
bool SLisPhiBinFilled(int ebin, int etabin, int phibin)
std::map< int, G4ThreeVector > PrimaryMomentum
double getTimeSlice() const
std::vector< double > SLEnergyBins
int FindEtaBin(double eta)
std::vector< int > PGParticleIDs
void update(const BeginOfJob *run) override
This routine will be called when the appropriate signal arrives.
Log< level::Warning, false > LogWarning
static uint32_t packIndex(int z, int sector, int zmodule)
void setNphotons(float np)
double getIncidentEnergy() const
Geom::Theta< T > theta() const
CastorShowerEvent * emShower
void setNhit(unsigned int i)
void setHitPosition(const Point &p)