28 #include "CLHEP/Units/GlobalSystemOfUnits.h" 29 #include "CLHEP/Units/GlobalPhysicalConstants.h" 42 DeActivatePhysicsProcess(
false),
65 for (
unsigned int i = 0;
i < PGParticleIDs.size();
i++) {
80 std::cout <<
"============================================================================" << std::endl;
81 std::cout <<
"CastorShowerLibraryMaker:: Initialized as observer" << std::endl;
82 std::cout <<
" Event Ntuple will be created" << std::endl;
83 std::cout <<
" Event Ntuple file: " << eventNtFileName << std::endl;
90 std::cout <<
"============================================================================" << std::endl;
100 nBinsEta = showerholder.
SLEtaBins.size();
101 nBinsPhi = showerholder.
SLPhiBins.size();
122 showerholder.
SLCollection.assign(nBinsE, std::vector<std::vector<std::vector<CastorShowerEvent> > >());
124 showerholder.
nEvtInBinEta.assign(nBinsE, std::vector<int>(0));
125 showerholder.
nEvtInBinPhi.assign(nBinsE, std::vector<std::vector<int> >());
126 for (
int i = 0;
i < nBinsE;
i++) {
127 showerholder.
SLCollection.at(
i).assign(nBinsEta, std::vector<std::vector<CastorShowerEvent> >());
129 showerholder.
nEvtInBinPhi.at(
i).assign(nBinsEta, std::vector<int>(0));
131 showerholder.
SLCollection.at(
i).at(
j).assign(nBinsPhi, std::vector<CastorShowerEvent>());
144 std::cout <<
"CastorShowerLibraryMaker: End of process" << std::endl;
149 std::cout <<
" CastorShowerLibraryMaker::Starting new job " << std::endl;
154 std::cout << std::endl <<
"CastorShowerLibraryMaker: Starting Run" << std::endl;
156 std::cout <<
"CastorShowerLibraryMaker: output event root file created" << std::endl;
159 theFile =
new TFile(eventfilename,
"RECREATE");
160 theTree =
new TTree(
"CastorCherenkovPhotons",
"Cherenkov Photons");
169 theTree->Branch(
"emShowerLibInfo.",
"CastorShowerLibraryInfo", &
emInfo, bsize, split);
170 theTree->Branch(
"emParticles.",
"CastorShowerEvent", &
emShower, bsize, split);
171 theTree->Branch(
"hadShowerLibInfo.",
"CastorShowerLibraryInfo", &
hadInfo, bsize, split);
172 theTree->Branch(
"hadParticles.",
"CastorShowerEvent", &
hadShower, bsize, split);
236 G4EventManager* e_mgr = G4EventManager::GetEventManager();
244 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
245 G4PrimaryParticle* thePrim =
thePrims.at(
i);
249 if (particleType == 11) {
251 SLType =
"Electromagnetic";
256 double px = 0.,
py = 0., pz = 0., pInit = 0.,
eta = 0.,
phi = 0.;
262 std::cout <<
"\n========================================================================" 263 <<
"\nBeginOfEvent: E : " << pInit <<
"\t bin : " << ebin <<
"\n Eta : " <<
eta 264 <<
"\t bin : " << etabin <<
"\n Phi : " <<
phi <<
"\t bin : " << phibin
265 <<
"\n========================================================================" << std::endl;
267 if (ebin < 0 || etabin < 0 || phibin < 0)
291 <<
"Event not accepted for ebin=" << ebin <<
",etabin=" << etabin <<
",phibin=" << phibin << std::endl;
299 if (NAccepted == 0) {
300 const_cast<G4Event*
>((*evt)())->SetEventAborted();
301 const_cast<G4Event*
>((*evt)())->KeepTheEvent((G4bool)
false);
302 e_mgr->AbortCurrentEvent();
306 std::cout <<
"CastorShowerLibraryMaker: Processing Event Number: " <<
eventIndex << std::endl;
311 static thread_local
int CurrentPrimary = 0;
312 G4Track* trk = aStep->GetTrack();
313 if (trk->GetCurrentStepNumber() == 1) {
314 if (trk->GetParentID() == 0) {
315 CurrentPrimary = (
int)trk->GetDynamicParticle()->GetPDGcode();
316 if (CurrentPrimary == 0)
317 SimG4Exception(
"CastorShowerLibraryMaker::update(G4Step) -> Primary particle undefined");
321 G4ProcessManager* p_mgr = trk->GetDefinition()->GetProcessManager();
322 G4ProcessVector* pvec = p_mgr->GetProcessList();
323 for (
int i = 0;
i < pvec->size();
i++) {
324 G4VProcess*
proc = (*pvec)(
i);
325 if (proc->GetProcessName() !=
"Transportation" && proc->GetProcessName() !=
"Decay") {
326 std::cout <<
"DeActivating process: " << proc->GetProcessName() << std::endl;
327 p_mgr->SetProcessActivation(proc,
false);
334 double t =
std::abs((pos.z() - trk->GetPosition().z())) / trk->GetVelocity();
335 double r = (pos.z() - trk->GetPosition().z()) / trk->GetMomentum().cosTheta();
336 pos.setX(r *
sin(trk->GetMomentum().theta()) *
cos(trk->GetMomentum().phi()) + trk->GetPosition().x());
337 pos.setY(r *
sin(trk->GetMomentum().theta()) *
sin(trk->GetMomentum().phi()) + trk->GetPosition().y());
338 trk->SetPosition(pos);
339 trk->SetGlobalTime(trk->GetGlobalTime() +
t);
340 trk->AddTrackLength(r);
342 std::cout <<
"CastorShowerLibraryMaker::update(G4Step) -> Killing spurious track" << std::endl;
343 trk->SetTrackStatus(fKillTrackAndSecondaries);
349 std::string CurVolume = trk->GetVolume()->GetName();
354 CurVolume ==
"CAST")) {
359 G4ProcessManager* p_mgr = trk->GetDefinition()->GetProcessManager();
360 G4ProcessVector* pvec = p_mgr->GetProcessList();
361 for (
int i = 0;
i < pvec->size();
i++) {
362 G4VProcess*
proc = (*pvec)(
i);
363 if (proc->GetProcessName() !=
"Transportation" && proc->GetProcessName() !=
"Decay") {
364 std::cout <<
" Activating process: " << proc->GetProcessName() << std::endl;
365 p_mgr->SetProcessActivation(proc,
true);
371 if (trk->GetMomentum().phi() >
MaxPhi || trk->GetMomentum().eta() >
MaxEta) {
372 trk->SetTrackStatus(fKillTrackAndSecondaries);
382 if (CurrentPrimary != 0 && trk->GetParentID() == 0 && !
InsideCastor) {
385 double pre_phi = aStep->GetPreStepPoint()->GetMomentum().phi();
386 double cur_phi = trk->GetMomentum().phi();
387 if (pre_phi != cur_phi) {
388 std::cout <<
"Primary track phi : " << pre_phi <<
" changed in current step: " << cur_phi
389 <<
" by processes:" << std::endl;
390 const G4VProcess*
proc = aStep->GetPreStepPoint()->GetProcessDefinedStep();
391 std::cout <<
" " << proc->GetProcessName() <<
" In volume " << CurVolume << std::endl;
412 if ((*evt)()->IsAborted()) {
413 std::cout <<
"\n========================================================================" 414 <<
"\nEndOfEvent: EVENT ABORTED" 415 <<
"\n========================================================================" << std::endl;
428 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"No valid primary particle found. Skipping event" << std::endl;
432 G4HCofThisEvent* allHC = (*evt)()->GetHCofThisEvent();
433 int CAFIid = G4SDManager::GetSDMpointer()->GetCollectionID(
"CastorFI");
436 edm::LogInfo(
"CastorShowerLibraryMaker") <<
" update(*evt) --> accessed all HC ";
437 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Found " << theCAFI->entries() <<
" hits in G4HitCollection";
438 if (theCAFI->entries() == 0) {
439 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n Empty G4HitCollection";
444 int NEvtAccepted = 0;
446 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
447 G4PrimaryParticle* thePrim =
thePrims.at(
i);
449 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"nullptr Pointer to the primary" << std::endl;
457 if (particleType == 11) {
459 SLType =
"Electromagnetic";
464 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n Primary (thePrim) trackID is " << thePrim->GetTrackID() <<
"\n";
467 double px = 0.,
py = 0., pz = 0., pInit = 0.,
eta = 0.,
phi = 0.;
472 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Primary did not hit CASTOR" << std::endl;
482 <<
"Event not accepted for ebin=" << ebin <<
",etabin=" << etabin <<
",phibin=" << phibin <<
"(" << pInit
483 <<
"," <<
eta <<
"," <<
phi <<
")" << std::endl;
491 <<
"\n CastorShowerLibraryMaker::update(EndOfEvent * evt) - event #" << (*evt)()->GetEventID();
520 NHitInEvent += shower->
getNhit();
528 if (NEvtAccepted ==
int(
thePrims.size()) && theCAFI->entries() != NHitInEvent) {
529 std::cout <<
"WARNING: Inconsistent Number of Hits -> Hits in collection: " << theCAFI->entries()
530 <<
" Hits in the showers: " << NHitInEvent << std::endl;
531 double miss_energy = 0;
532 double tot_energy = 0;
534 if (miss_energy > 0) {
535 std::cout <<
"Total missing energy: " << miss_energy <<
" for an incident energy: " << tot_energy << std::endl;
565 unsigned int ibine, ibineta, ibinphi, ievt;
566 unsigned int jbine, jbineta, jbinphi, jevt;
568 ibine = ibineta = ibinphi = ievt = jbine = jbineta = jbinphi = jevt = 0;
573 int maxEvtInTree =
std::max(nEMevt, nHadevt);
578 while (nEvtInTree < maxEvtInTree) {
619 if (nEvtInTree == 1) {
620 theTree->SetBranchStatus(
"emShowerLibInfo.",
false);
621 theTree->SetBranchStatus(
"hadShowerLibInfo.",
false);
626 throw SimG4Exception(
"\n\nNumber of needed trigger events reached in CastorShowerLibraryMaker\n\n");
634 theTree->Write(
"", TObject::kOverwrite);
635 std::cout <<
"CastorShowerLibraryMaker: Ntuple event written" << std::endl;
637 std::cout <<
"CastorShowerLibraryMaker: Event file closed" << std::endl;
651 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindEnergyBin can be called only after BeginOfEvent\n\n";
652 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
655 if (energy >= SLenergies.back())
656 return SLenergies.size() - 1;
659 for (; i < SLenergies.size() - 1; i++)
660 if (energy >= SLenergies.at(i) && energy < SLenergies.at(i + 1))
664 if (energy >= SLenergies.at(i))
675 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindEtaBin can be called only after BeginOfEvent\n\n";
676 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
679 if (eta >= SLetas.back())
680 return SLetas.size() - 1;
682 for (; i < SLetas.size() - 1; i++)
683 if (eta >= SLetas.at(i) && eta < SLetas.at(i + 1))
686 if (eta >= SLetas.at(i))
699 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindPhiBin can be called only after BeginOfEvent\n\n";
700 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
703 if (phi >= SLphis.back())
704 return SLphis.size() - 1;
706 for (; i < SLphis.size() - 1; i++)
707 if (phi >= SLphis.at(i) && phi < SLphis.at(i + 1))
710 if (phi >= SLphis.at(i))
718 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nIsSLReady must be called when a new event starts.\n\n";
719 throw SimG4Exception(
"\n\nNOT nullptr Pointer to the shower library.\n\n");
744 int thePrim,
double&
px,
double&
py,
double& pz,
double& pInit,
double&
eta,
double&
phi) {
755 double costheta = pz / pInit;
757 eta = -
log(
tan(theta / 2.0));
758 phi = (px == 0 && py == 0) ? 0 : atan2(py, px);
762 G4PrimaryParticle* thePrim,
double&
px,
double&
py,
double& pz,
double& pInit,
double&
eta,
double&
phi) {
763 px = py = pz = phi = eta = 0.0;
764 if (thePrim ==
nullptr)
766 px = thePrim->GetMomentum().x() /
GeV;
767 py = thePrim->GetMomentum().y() /
GeV;
768 pz = thePrim->GetMomentum().z() /
GeV;
769 pInit = thePrim->GetMomentum().mag() /
GeV;
773 double costheta = pz / pInit;
775 eta = -
log(
tan(theta / 2.0));
776 phi = (px == 0 && py == 0) ? 0 : atan2(py, px);
777 phi = thePrim->GetMomentum().phi();
783 std::vector<G4PrimaryParticle*>
thePrims;
784 G4PrimaryParticle* thePrim =
nullptr;
785 G4int nvertex = evt->GetNumberOfPrimaryVertex();
786 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Event has " << nvertex <<
" vertex";
788 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"CastorShowerLibraryMaker::GetPrimary ERROR: no vertex";
792 for (
int i = 0;
i < nvertex;
i++) {
793 G4PrimaryVertex* avertex = evt->GetPrimaryVertex(
i);
794 if (avertex ==
nullptr) {
795 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"CastorShowerLibraryMaker::GetPrimary ERROR: pointer to vertex = 0";
798 unsigned int npart = avertex->GetNumberOfParticle();
801 for (
unsigned int j = 0;
j <
npart;
j++) {
805 thePrim = avertex->GetPrimary(trackID);
811 thePrims.push_back(thePrim);
818 edm::LogInfo(
"CastorShowerLibraryInfo") <<
"nullptr shower pointer. Printing both";
819 std::cout <<
"Electromagnetic" << std::endl;
832 for (
int n = 0;
n < 11 + (nBinsEta *
nBinsPhi);
n++)
835 for (
int i = 0;
i < nBinsE;
i++) {
836 std::cout <<
"E bin " << std::setw(6) << SLenergies.at(
i) <<
" : ";
841 if (
j < nBinsEta - 1)
853 if (
j < nBinsEta - 1)
858 for (
int n = 0;
n < 11 + (nBinsEta *
nBinsPhi);
n++)
864 edm::LogInfo(
"CastorShowerLibraryMaker::SLacceptEvent:") <<
"Error. nullptr pointer to CastorShowerEvent";
884 unsigned int volumeID = 0;
885 double en_in_fi = 0.;
888 int nentries = theCAFI->entries();
898 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Error. nullptr pointer to CastorShowerEvent";
908 for (
int ihit = 0; ihit < nentries; ihit++) {
913 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Skipping hit from trackID " << hit_particleID;
920 int zside, sector, zmodule;
921 theCastorNumScheme->
unpackIndex(volumeID, zside, sector, zmodule);
925 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n side , sector , module = " << zside <<
" , " << sector <<
" , " 926 << zmodule <<
"\n nphotons = " << hitEnergy;
930 <<
"\n packIndex = " << theCastorNumScheme->
packIndex(zside, sector, zmodule);
934 <<
"\n nentries = " << nentries <<
"\n time[" << ihit <<
"] = " << time <<
"\n trackID[" << ihit
935 <<
"] = " << aHit->
getTrackID() <<
"\n volumeID[" << ihit <<
"] = " << volumeID <<
"\n nphotons[" << ihit
936 <<
"] = " << hitEnergy <<
"\n side, sector, module = " << zside <<
", " << sector <<
", " << zmodule
937 <<
"\n packIndex " << theCastorNumScheme->
packIndex(zside, sector, zmodule) <<
"\n X,Y,Z = " << entry.x()
938 <<
"," << entry.y() <<
"," << entry.z();
952 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"No hits found for this track (trackID=" << ipart <<
")." << std::endl;
953 if (theCastorNumScheme)
954 delete theCastorNumScheme;
960 if (theCastorNumScheme)
961 delete theCastorNumScheme;
966 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinE can be called only after BeginOfEvent\n\n";
967 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
974 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinEta can be called only after BeginOfEvent\n\n";
975 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
982 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinPhi can be called only after BeginOfEvent\n\n";
983 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
989 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisEBinFilled can be called only after BeginOfEvent\n\n";
990 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
998 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisEtaBinFilled can be called only after BeginOfEvent\n\n";
999 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1007 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisPhiBinFilled can be called only after BeginOfEvent\n\n";
1008 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1015 const G4TrackVector* p_sec = aStep->GetSecondary();
1016 for (
int i = 0;
i <
int(p_sec->size());
i++) {
1017 std::cout <<
"Killing track ID " << p_sec->at(
i)->GetTrackID() <<
" and its secondaries" 1018 <<
" Produced by Process " << p_sec->at(
i)->GetCreatorProcess()->GetProcessName()
1019 <<
" in the volume " << aStep->GetTrack()->GetVolume()->GetName() << std::endl;
1020 p_sec->at(
i)->SetTrackStatus(fKillTrackAndSecondaries);
1028 for (
int ihit = 0; ihit < theCAFI->entries(); ihit++) {
1029 int id = (*theCAFI)[ihit]->getTrackID();
1030 tot_energy += (*theCAFI)[ihit]->getEnergyDeposit();
1032 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
1037 if (hit_prim == 0) {
1038 std::cout <<
"Track ID " <<
id <<
" produced a hit which is not associated with a primary." << std::endl;
1039 miss_energy += (*theCAFI)[ihit]->getEnergyDeposit();
std::string eventNtFileName
std::vector< double > SLEtaBins
void Clear(Option_t *option="") override
std::vector< std::string_view > split(std::string_view, const char *)
T getParameter(std::string const &) const
void setNBins(unsigned int n)
math::XYZPoint getPosition() 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)
Geom::Theta< T > theta() const
bool FillShowerEvent(CaloG4HitCollection *, CastorShowerEvent *, int)
double getIncidentEnergy() const
std::map< int, G4ThreeVector > PrimaryPosition
void KillSecondaries(const G4Step *step)
void InitSLHolder(ShowerLib &)
void printSLstatus(int, int, int)
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
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)
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
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)
math::XYZPoint getEntry() const
std::vector< int > PGParticleIDs
void update(const BeginOfJob *run) override
This routine will be called when the appropriate signal arrives.
uint32_t getUnitID() const
static uint32_t packIndex(int z, int sector, int zmodule)
void setNphotons(float np)
CastorShowerEvent * emShower
void setNhit(unsigned int i)
void setHitPosition(const Point &p)
double getEnergyDeposit() const