28 #include "CLHEP/Units/GlobalSystemOfUnits.h" 29 #include "CLHEP/Units/GlobalPhysicalConstants.h" 39 NPGParticle(0),DoHadSL(
false),DoEmSL(
false),DeActivatePhysicsProcess(
false),
62 for(
unsigned int i=0;
i<PGParticleIDs.size();
i++) {
77 std::cout <<
"============================================================================"<<std::endl;
78 std::cout <<
"CastorShowerLibraryMaker:: Initialized as observer" << std::endl;
79 std::cout <<
" Event Ntuple will be created" << std::endl;
80 std::cout <<
" Event Ntuple file: " << eventNtFileName << std::endl;
87 std::cout <<
"============================================================================"<<std::endl;
96 int nBinsE,nBinsEta,nBinsPhi,nEvtPerBinPhi;
120 showerholder.
SLCollection.assign(nBinsE,std::vector<std::vector<std::vector<CastorShowerEvent> > >());
122 showerholder.
nEvtInBinEta.assign(nBinsE,std::vector<int>(0));
123 showerholder.
nEvtInBinPhi.assign(nBinsE,std::vector<std::vector<int> >());
124 for(
int i=0;
i<nBinsE;
i++) {
125 showerholder.
SLCollection.at(
i).assign(nBinsEta,std::vector<std::vector<CastorShowerEvent> >());
127 showerholder.
nEvtInBinPhi.at(
i).assign(nBinsEta,std::vector<int>(0));
128 for(
int j=0;j<nBinsEta;j++) {
129 showerholder.
SLCollection.at(
i).at(j).assign(nBinsPhi,std::vector<CastorShowerEvent>());
131 for(
int k=0;
k<nBinsPhi;
k++)
143 std::cout <<
"CastorShowerLibraryMaker: End of process" << std::endl;
150 std::cout <<
" CastorShowerLibraryMaker::Starting new job " << std::endl;
156 std::cout << std::endl <<
"CastorShowerLibraryMaker: Starting Run"<< std::endl;
158 std::cout <<
"CastorShowerLibraryMaker: output event root file created" << std::endl;
161 theFile =
new TFile(eventfilename,
"RECREATE");
162 theTree =
new TTree(
"CastorCherenkovPhotons",
"Cherenkov Photons");
171 theTree->Branch(
"emShowerLibInfo.",
"CastorShowerLibraryInfo", &
emInfo, bsize, split);
172 theTree->Branch(
"emParticles.",
"CastorShowerEvent", &
emShower, bsize, split);
173 theTree->Branch(
"hadShowerLibInfo.",
"CastorShowerLibraryInfo", &
hadInfo, bsize, split);
174 theTree->Branch(
"hadParticles.",
"CastorShowerEvent", &
hadShower, bsize, split);
240 G4EventManager *e_mgr = G4EventManager::GetEventManager();
249 G4PrimaryParticle* thePrim =
thePrims.at(
i);
253 if (particleType==11) {
255 SLType =
"Electromagnetic";
261 double px=0., py=0., pz=0., pInit = 0.,
eta = 0.,
phi = 0.;
267 std::cout <<
"\n========================================================================" 268 <<
"\nBeginOfEvent: E : " << pInit <<
"\t bin : " << ebin
269 <<
"\n Eta : " <<
eta <<
"\t bin : " << etabin
270 <<
"\n Phi : " <<
phi <<
"\t bin : " << phibin
271 <<
"\n========================================================================" 274 if (ebin<0||etabin<0||phibin<0)
continue;
295 if (!accept)
edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Event not accepted for ebin=" 296 << ebin<<
",etabin="<<etabin<<
",phibin="<<phibin<<std::endl;
301 if (accept) NAccepted++;
305 const_cast<G4Event*
>((*evt)())->SetEventAborted();
306 const_cast<G4Event*
>((*evt)())->KeepTheEvent((G4bool)
false);
307 e_mgr->AbortCurrentEvent();
311 std::cout <<
"CastorShowerLibraryMaker: Processing Event Number: " <<
eventIndex << std::endl;
316 static thread_local
int CurrentPrimary = 0;
317 G4Track *trk = aStep->GetTrack();
318 if (trk->GetCurrentStepNumber()==1) {
319 if (trk->GetParentID()==0) {
320 CurrentPrimary = (
int)trk->GetDynamicParticle()->GetPDGcode();
321 if (CurrentPrimary==0)
322 SimG4Exception(
"CastorShowerLibraryMaker::update(G4Step) -> Primary particle undefined");
326 G4ProcessManager *p_mgr = trk->GetDefinition()->GetProcessManager();
327 G4ProcessVector *pvec = p_mgr->GetProcessList();
328 for (
int i = 0;
i<pvec->size();
i++) {
329 G4VProcess *
proc = (*pvec)(
i);
330 if (proc->GetProcessName()!=
"Transportation"&&
331 proc->GetProcessName()!=
"Decay") {
332 std::cout <<
"DeActivating process: " << proc->GetProcessName() << std::endl;
333 p_mgr->SetProcessActivation(proc,
false);
340 double t =
std::abs((pos.z()-trk->GetPosition().z()))/trk->GetVelocity();
341 double r = (pos.z()-trk->GetPosition().z())/trk->GetMomentum().cosTheta();
342 pos.setX(r*
sin(trk->GetMomentum().theta())*
cos(trk->GetMomentum().phi())+trk->GetPosition().x());
343 pos.setY(r*
sin(trk->GetMomentum().theta())*
sin(trk->GetMomentum().phi())+trk->GetPosition().y());
344 trk->SetPosition(pos);
345 trk->SetGlobalTime(trk->GetGlobalTime()+
t);
346 trk->AddTrackLength(r);
349 std::cout<<
"CastorShowerLibraryMaker::update(G4Step) -> Killing spurious track" << std::endl;
350 trk->SetTrackStatus(fKillTrackAndSecondaries);
356 std::string CurVolume = trk->GetVolume()->GetName();
361 CurVolume==
"CAST")) {
366 G4ProcessManager *p_mgr = trk->GetDefinition()->GetProcessManager();
367 G4ProcessVector *pvec = p_mgr->GetProcessList();
368 for (
int i = 0;
i<pvec->size();
i++) {
369 G4VProcess *
proc = (*pvec)(
i);
370 if (proc->GetProcessName()!=
"Transportation"&&
371 proc->GetProcessName()!=
"Decay") {
372 std::cout <<
" Activating process: " << proc->GetProcessName() << std::endl;
373 p_mgr->SetProcessActivation(proc,
true);
379 if (trk->GetMomentum().phi()>
MaxPhi||trk->GetMomentum().eta()>
MaxEta) {
380 trk->SetTrackStatus(fKillTrackAndSecondaries);
390 if (CurrentPrimary!=0&&trk->GetParentID()==0&&!
InsideCastor) {
393 double pre_phi = aStep->GetPreStepPoint()->GetMomentum().phi();
394 double cur_phi = trk->GetMomentum().phi();
395 if (pre_phi!=cur_phi) {
396 std::cout <<
"Primary track phi : " << pre_phi <<
" changed in current step: " 397 << cur_phi <<
" by processes:" << std::endl;
398 const G4VProcess *
proc = aStep->GetPreStepPoint()->GetProcessDefinedStep();
399 std::cout <<
" " << proc->GetProcessName()
400 <<
" In volume " << CurVolume << std::endl;
422 if ((*evt)()->IsAborted()) {
423 std::cout <<
"\n========================================================================" 424 <<
"\nEndOfEvent: EVENT ABORTED" 425 <<
"\n========================================================================" 439 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"No valid primary particle found. Skipping event" << std::endl;
443 G4HCofThisEvent* allHC = (*evt)()->GetHCofThisEvent();
444 int CAFIid = G4SDManager::GetSDMpointer()->GetCollectionID(
"CastorFI");
447 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Found "<<theCAFI->entries() <<
" hits in G4HitCollection";
448 if (theCAFI->entries()== 0) {
449 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n Empty G4HitCollection";
454 int NEvtAccepted = 0;
457 G4PrimaryParticle* thePrim =
thePrims.at(
i);
459 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"nullptr Pointer to the primary" << std::endl;
467 if (particleType==11) {
469 SLType =
"Electromagnetic";
475 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n Primary (thePrim) trackID is " << thePrim->GetTrackID() <<
"\n" ;
478 double px=0., py=0., pz=0., pInit = 0.,
eta = 0.,
phi = 0.;
483 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Primary did not hit CASTOR" << std::endl;
492 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Event not accepted for ebin=" 493 << ebin<<
",etabin="<<etabin<<
",phibin="<<phibin
494 <<
"("<< pInit <<
","<<
eta<<
","<<
phi<<
")" <<std::endl;
502 <<
"\n CastorShowerLibraryMaker::update(EndOfEvent * evt) - event #" 503 << (*evt)()->GetEventID() ;
532 NHitInEvent+=shower->
getNhit();
535 else {shower->
Clear();}
539 if (NEvtAccepted==
int(
thePrims.size())&&theCAFI->entries()!=NHitInEvent){
540 std::cout <<
"WARNING: Inconsistent Number of Hits -> Hits in collection: "<< theCAFI->entries()
541 <<
" Hits in the showers: " << NHitInEvent << std::endl;
542 double miss_energy=0;
546 std::cout <<
"Total missing energy: " << miss_energy
547 <<
" for an incident energy: " << tot_energy
578 unsigned int ibine,ibineta,ibinphi,ievt;
579 unsigned int jbine,jbineta,jbinphi,jevt;
581 ibine=ibineta=ibinphi=ievt=jbine=jbineta=jbinphi=jevt=0;
586 int maxEvtInTree=
std::max(nEMevt,nHadevt);
591 while(nEvtInTree<maxEvtInTree) {
613 theTree->SetBranchStatus(
"emShowerLibInfo.",
false);
614 theTree->SetBranchStatus(
"hadShowerLibInfo.",
false);
618 if (run==
nullptr)
throw SimG4Exception(
"\n\nNumber of needed trigger events reached in CastorShowerLibraryMaker\n\n");
627 theTree->Write(
"",TObject::kOverwrite);
628 std::cout <<
"CastorShowerLibraryMaker: Ntuple event written" << std::endl;
630 std::cout <<
"CastorShowerLibraryMaker: Event file closed" << std::endl;
644 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindEnergyBin can be called only after BeginOfEvent\n\n";
645 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
648 if (energy >= SLenergies.back())
return SLenergies.size()-1;
651 for(;i<SLenergies.size()-1;i++)
652 if (energy >= SLenergies.at(i) && energy < SLenergies.at(i+1))
return (
int)
i;
655 if (energy>=SLenergies.at(i))
return (
int)
i;
665 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindEtaBin can be called only after BeginOfEvent\n\n";
666 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
669 if (eta>=SLetas.back())
return SLetas.size()-1;
671 for(;i<SLetas.size()-1;i++)
672 if (eta >= SLetas.at(i) && eta < SLetas.at(i+1))
return (
int)
i;
674 if (eta>=SLetas.at(i))
return (
int)
i;
686 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindPhiBin can be called only after BeginOfEvent\n\n";
687 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
690 if (phi>=SLphis.back())
return SLphis.size()-1;
692 for(;i<SLphis.size()-1;i++)
693 if (phi >= SLphis.at(i) && phi < SLphis.at(i+1))
return (
int)
i;
695 if (phi>=SLphis.at(i))
return (
int)
i;
703 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nIsSLReady must be called when a new event starts.\n\n";
704 throw SimG4Exception(
"\n\nNOT nullptr Pointer to the shower library.\n\n");
730 if (thePrim==0)
return;
736 if (pInit==0)
return;
737 double costheta = pz/pInit;
739 eta = -
log(
tan(theta/2.0));
740 phi = (px==0 && py==0) ? 0 : atan2(py,px);
745 px=py=pz=phi=eta=0.0;
746 if (thePrim==
nullptr)
return;
747 px = thePrim->GetMomentum().x()/
GeV;
748 py = thePrim->GetMomentum().y()/
GeV;
749 pz = thePrim->GetMomentum().z()/
GeV;
750 pInit = thePrim->GetMomentum().mag()/
GeV;
752 if (pInit==0)
return;
753 double costheta = pz/pInit;
755 eta = -
log(
tan(theta/2.0));
756 phi = (px==0 && py==0) ? 0 : atan2(py,px);
757 phi = thePrim->GetMomentum().phi();
764 std::vector<G4PrimaryParticle*>
thePrims;
765 G4PrimaryParticle* thePrim =
nullptr;
766 G4int nvertex = evt->GetNumberOfPrimaryVertex();
767 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Event has " << nvertex <<
" vertex";
769 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"CastorShowerLibraryMaker::GetPrimary ERROR: no vertex";
773 for (
int i = 0 ;
i<nvertex;
i++) {
774 G4PrimaryVertex* avertex = evt->GetPrimaryVertex(
i);
775 if (avertex ==
nullptr) {
777 <<
"CastorShowerLibraryMaker::GetPrimary ERROR: pointer to vertex = 0";
780 unsigned int npart = avertex->GetNumberOfParticle();
782 for (
unsigned int j=0;j<
npart;j++) {
786 thePrim=avertex->GetPrimary(trackID);
789 thePrims.push_back(thePrim);
797 edm::LogInfo(
"CastorShowerLibraryInfo") <<
"nullptr shower pointer. Printing both";
798 std::cout <<
"Electromagnetic" << std::endl;
811 for(
int n=0;
n<11+(nBinsEta*nBinsPhi);
n++)
std::cout <<
"=";
813 for(
int i=0;
i<nBinsE;
i++) {
814 std::cout <<
"E bin " << std::setw(6) << SLenergies.at(
i) <<
" : ";
815 for(
int j=0;j<nBinsEta;j++) {
816 for(
int k=0;
k<nBinsPhi;
k++) {
823 if (ebin!=
i)
continue;
825 for(
int j=0;j<nBinsEta;j++) {
826 for(
int k=0;
k<nBinsPhi;
k++) {
833 for(
int n=0;
n<11+(nBinsEta*nBinsPhi);
n++)
std::cout <<
"=";
839 edm::LogInfo(
"CastorShowerLibraryMaker::SLacceptEvent:") <<
"Error. nullptr pointer to CastorShowerEvent";
854 unsigned int volumeID=0;
855 double en_in_fi = 0.;
858 int nentries = theCAFI->entries();
868 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Error. nullptr pointer to CastorShowerEvent";
878 for (
int ihit = 0; ihit < nentries; ihit++) {
883 <<
"Skipping hit from trackID " << hit_particleID;
890 int zside, sector, zmodule;
891 theCastorNumScheme->
unpackIndex(volumeID, zside, sector,zmodule);
895 <<
"\n side , sector , module = " << zside <<
" , " 896 << sector <<
" , " << zmodule
897 <<
"\n nphotons = " << hitEnergy ;
901 << theCastorNumScheme->
packIndex(zside, sector,zmodule);
905 <<
"\n nentries = " << nentries
906 <<
"\n time[" << ihit <<
"] = " << time
907 <<
"\n trackID[" << ihit <<
"] = " << aHit->
getTrackID()
908 <<
"\n volumeID[" << ihit <<
"] = " << volumeID
909 <<
"\n nphotons[" << ihit <<
"] = " << hitEnergy
910 <<
"\n side, sector, module = " << zside <<
", " << sector<<
", " << zmodule
911 <<
"\n packIndex " << theCastorNumScheme->
packIndex(zside,sector,zmodule)
912 <<
"\n X,Y,Z = " << entry.x() <<
","<< entry.y() <<
"," << entry.z();
926 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"No hits found for this track (trackID=" << ipart <<
")." << std::endl;
927 if (theCastorNumScheme)
delete theCastorNumScheme;
933 if (theCastorNumScheme)
delete theCastorNumScheme;
939 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinE can be called only after BeginOfEvent\n\n";
940 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
948 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinEta can be called only after BeginOfEvent\n\n";
949 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
957 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinPhi can be called only after BeginOfEvent\n\n";
958 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
965 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisEBinFilled can be called only after BeginOfEvent\n\n";
966 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
974 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisEtaBinFilled can be called only after BeginOfEvent\n\n";
975 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
983 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisPhiBinFilled can be called only after BeginOfEvent\n\n";
984 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
990 const G4TrackVector *p_sec = aStep->GetSecondary();
991 for(
int i=0;
i<
int(p_sec->size());
i++) {
992 std::cout <<
"Killing track ID " << p_sec->at(
i)->GetTrackID() <<
" and its secondaries" 993 <<
" Produced by Process " << p_sec->at(
i)->GetCreatorProcess()->GetProcessName()
994 <<
" in the volume " << aStep->GetTrack()->GetVolume()->GetName()
996 p_sec->at(
i)->SetTrackStatus(fKillTrackAndSecondaries);
1004 for (
int ihit = 0; ihit < theCAFI->entries(); ihit++) {
1005 int id = (*theCAFI)[ihit]->getTrackID();
1006 tot_energy+=(*theCAFI)[ihit]->getEnergyDeposit();
1014 std::cout <<
"Track ID " <<
id <<
" produced a hit which is not associated with a primary." 1016 miss_energy+=(*theCAFI)[ihit]->getEnergyDeposit();
std::string eventNtFileName
std::vector< double > SLEtaBins
void Clear(Option_t *option="") override
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)
TrainProcessor *const proc
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
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::vector< G4PrimaryParticle * > GetPrimary(const G4Event *)
bool SLisEBinFilled(int ebin)
CastorShowerLibraryInfo * hadInfo
std::vector< int > nEvtInBinE
int FindEnergyBin(double e)
~CastorShowerLibraryMaker() override
std::map< int, G4ThreeVector > PrimaryMomentum
Cos< T >::type cos(const T &t)
std::map< int, G4ThreeVector > PrimaryPosition
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
std::map< int, std::set< int > > MapOfSecondaries
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)
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