27 #include "CLHEP/Units/GlobalSystemOfUnits.h"
28 #include "CLHEP/Units/GlobalPhysicalConstants.h"
38 NPGParticle(0),DoHadSL(
false),DoEmSL(
false),DeActivatePhysicsProcess(
false),
61 for(
unsigned int i=0;
i<PGParticleIDs.size();
i++) {
62 switch (
int(fabs(PGParticleIDs.at(
i)))) {
76 std::cout <<
"============================================================================"<<std::endl;
77 std::cout <<
"CastorShowerLibraryMaker:: Initialized as observer" << std::endl;
78 std::cout <<
" Event Ntuple will be created" << std::endl;
79 std::cout <<
" Event Ntuple file: " << eventNtFileName << std::endl;
86 std::cout <<
"============================================================================"<<std::endl;
95 int nBinsE,nBinsEta,nBinsPhi,nEvtPerBinPhi;
119 showerholder.
SLCollection.assign(nBinsE,std::vector<std::vector<std::vector<CastorShowerEvent> > >());
121 showerholder.
nEvtInBinEta.assign(nBinsE,std::vector<int>(0));
122 showerholder.
nEvtInBinPhi.assign(nBinsE,std::vector<std::vector<int> >());
123 for(
int i=0;
i<nBinsE;
i++) {
124 showerholder.
SLCollection.at(
i).assign(nBinsEta,std::vector<std::vector<CastorShowerEvent> >());
126 showerholder.
nEvtInBinPhi.at(
i).assign(nBinsEta,std::vector<int>(0));
127 for(
int j=0;
j<nBinsEta;
j++) {
128 showerholder.
SLCollection.at(
i).at(
j).assign(nBinsPhi,std::vector<CastorShowerEvent>());
130 for(
int k=0;
k<nBinsPhi;
k++)
142 std::cout <<
"CastorShowerLibraryMaker: End of process" << std::endl;
149 std::cout <<
" CastorShowerLibraryMaker::Starting new job " << std::endl;
155 std::cout << std::endl <<
"CastorShowerLibraryMaker: Starting Run"<< std::endl;
157 std::cout <<
"CastorShowerLibraryMaker: output event root file created" << std::endl;
160 theFile =
new TFile(eventfilename,
"RECREATE");
161 theTree =
new TTree(
"CastorCherenkovPhotons",
"Cherenkov Photons");
170 theTree->Branch(
"emShowerLibInfo.",
"CastorShowerLibraryInfo", &
emInfo, bsize, split);
171 theTree->Branch(
"emParticles.",
"CastorShowerEvent", &
emShower, bsize, split);
172 theTree->Branch(
"hadShowerLibInfo.",
"CastorShowerLibraryInfo", &
hadInfo, bsize, split);
173 theTree->Branch(
"hadParticles.",
"CastorShowerEvent", &
hadShower, bsize, split);
239 G4EventManager *e_mgr = G4EventManager::GetEventManager();
248 G4PrimaryParticle* thePrim =
thePrims.at(
i);
249 int particleType = thePrim->GetPDGcode();
252 if (particleType==11) {
254 SLType =
"Electromagnetic";
260 double px=0., py=0., pz=0., pInit = 0.,
eta = 0.,
phi = 0.;
266 std::cout <<
"\n========================================================================"
267 <<
"\nBeginOfEvent: E : " << pInit <<
"\t bin : " << ebin
268 <<
"\n Eta : " <<
eta <<
"\t bin : " << etabin
269 <<
"\n Phi : " <<
phi <<
"\t bin : " << phibin
270 <<
"\n========================================================================"
273 if (ebin<0||etabin<0||phibin<0)
continue;
294 if (!accept)
edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Event not accepted for ebin="
295 << ebin<<
",etabin="<<etabin<<
",phibin="<<phibin<<std::endl;
300 if (accept) NAccepted++;
304 const_cast<G4Event*
>((*evt)())->SetEventAborted();
305 const_cast<G4Event*
>((*evt)())->KeepTheEvent((G4bool)
false);
306 e_mgr->AbortCurrentEvent();
310 std::cout <<
"CastorShowerLibraryMaker: Processing Event Number: " <<
eventIndex << std::endl;
315 static int CurrentPrimary = 0;
316 G4Track *trk = aStep->GetTrack();
317 if (trk->GetCurrentStepNumber()==1) {
318 if (trk->GetParentID()==0) {
319 CurrentPrimary = (int)trk->GetDynamicParticle()->GetPDGcode();
320 if (CurrentPrimary==0)
321 SimG4Exception(
"CastorShowerLibraryMaker::update(G4Step) -> Primary particle undefined");
325 G4ProcessManager *p_mgr = trk->GetDefinition()->GetProcessManager();
326 G4ProcessVector *pvec = p_mgr->GetProcessList();
327 for (
int i = 0;
i<pvec->size();
i++) {
328 G4VProcess *
proc = (*pvec)(
i);
329 if (proc->GetProcessName()!=
"Transportation"&&
330 proc->GetProcessName()!=
"Decay") {
331 std::cout <<
"DeActivating process: " << proc->GetProcessName() << std::endl;
332 p_mgr->SetProcessActivation(proc,
false);
339 double t =
abs((pos.z()-trk->GetPosition().z()))/trk->GetVelocity();
340 double r = (pos.z()-trk->GetPosition().z())/trk->GetMomentum().cosTheta();
341 pos.setX(r*
sin(trk->GetMomentum().theta())*
cos(trk->GetMomentum().phi())+trk->GetPosition().x());
342 pos.setY(r*
sin(trk->GetMomentum().theta())*
sin(trk->GetMomentum().phi())+trk->GetPosition().y());
343 trk->SetPosition(pos);
344 trk->SetGlobalTime(trk->GetGlobalTime()+
t);
345 trk->AddTrackLength(r);
348 std::cout<<
"CastorShowerLibraryMaker::update(G4Step) -> Killing spurious track" << std::endl;
349 trk->SetTrackStatus(fKillTrackAndSecondaries);
355 std::string CurVolume = trk->GetVolume()->GetName();
360 CurVolume==
"CAST")) {
365 G4ProcessManager *p_mgr = trk->GetDefinition()->GetProcessManager();
366 G4ProcessVector *pvec = p_mgr->GetProcessList();
367 for (
int i = 0;
i<pvec->size();
i++) {
368 G4VProcess *
proc = (*pvec)(
i);
369 if (proc->GetProcessName()!=
"Transportation"&&
370 proc->GetProcessName()!=
"Decay") {
371 std::cout <<
" Activating process: " << proc->GetProcessName() << std::endl;
372 p_mgr->SetProcessActivation(proc,
true);
378 if (trk->GetMomentum().phi()>
MaxPhi||trk->GetMomentum().eta()>
MaxEta) {
379 trk->SetTrackStatus(fKillTrackAndSecondaries);
389 if (CurrentPrimary!=0&&trk->GetParentID()==0&&!
InsideCastor) {
392 double pre_phi = aStep->GetPreStepPoint()->GetMomentum().phi();
393 double cur_phi = trk->GetMomentum().phi();
394 if (pre_phi!=cur_phi) {
395 std::cout <<
"Primary track phi : " << pre_phi <<
" changed in current step: "
396 << cur_phi <<
" by processes:" << std::endl;
397 const G4VProcess *
proc = aStep->GetPreStepPoint()->GetProcessDefinedStep();
398 std::cout <<
" " << proc->GetProcessName()
399 <<
" In volume " << CurVolume << std::endl;
421 if ((*evt)()->IsAborted()) {
422 std::cout <<
"\n========================================================================"
423 <<
"\nEndOfEvent: EVENT ABORTED"
424 <<
"\n========================================================================"
438 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"No valid primary particle found. Skipping event" << std::endl;
442 G4HCofThisEvent* allHC = (*evt)()->GetHCofThisEvent();
443 int CAFIid = G4SDManager::GetSDMpointer()->GetCollectionID(
"CastorFI");
446 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Found "<<theCAFI->entries() <<
" hits in G4HitCollection";
447 if (theCAFI->entries()== 0) {
448 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n Empty G4HitCollection";
453 int NEvtAccepted = 0;
456 G4PrimaryParticle* thePrim =
thePrims.at(
i);
458 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"NULL Pointer to the primary" << std::endl;
462 int particleType = thePrim->GetPDGcode();
466 if (particleType==11) {
468 SLType =
"Electromagnetic";
474 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n Primary (thePrim) trackID is " << thePrim->GetTrackID() <<
"\n" ;
477 double px=0., py=0., pz=0., pInit = 0.,
eta = 0.,
phi = 0.;
482 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Primary did not hit CASTOR" << std::endl;
491 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Event not accepted for ebin="
492 << ebin<<
",etabin="<<etabin<<
",phibin="<<phibin
493 <<
"("<< pInit <<
","<<
eta<<
","<<
phi<<
")" <<std::endl;
501 <<
"\n CastorShowerLibraryMaker::update(EndOfEvent * evt) - event #"
502 << (*evt)()->GetEventID() ;
531 NHitInEvent+=shower->
getNhit();
534 else {shower->
Clear();}
538 if (NEvtAccepted==
int(
thePrims.size())&&theCAFI->entries()!=NHitInEvent){
539 std::cout <<
"WARNING: Inconsistent Number of Hits -> Hits in collection: "<< theCAFI->entries()
540 <<
" Hits in the showers: " << NHitInEvent << std::endl;
541 double miss_energy=0;
545 std::cout <<
"Total missing energy: " << miss_energy
546 <<
" for an incident energy: " << tot_energy
577 unsigned int ibine,ibineta,ibinphi,ievt;
578 unsigned int jbine,jbineta,jbinphi,jevt;
580 ibine=ibineta=ibinphi=ievt=jbine=jbineta=jbinphi=jevt=0;
585 int maxEvtInTree=
std::max(nEMevt,nHadevt);
590 while(nEvtInTree<maxEvtInTree) {
612 theTree->SetBranchStatus(
"emShowerLibInfo.",0);
613 theTree->SetBranchStatus(
"hadShowerLibInfo.",0);
617 if (run==
NULL)
throw SimG4Exception(
"\n\nNumber of needed trigger events reached in CastorShowerLibraryMaker\n\n");
626 theTree->Write(
"",TObject::kOverwrite);
627 std::cout <<
"CastorShowerLibraryMaker: Ntuple event written" << std::endl;
629 std::cout <<
"CastorShowerLibraryMaker: Event file closed" << std::endl;
643 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindEnergyBin can be called only after BeginOfEvent\n\n";
644 throw SimG4Exception(
"\n\nNULL Pointer to the shower library.\n\n");
647 if (energy >= SLenergies.back())
return SLenergies.size()-1;
650 for(;i<SLenergies.size()-1;i++)
651 if (energy >= SLenergies.at(i) && energy < SLenergies.at(i+1))
return (
int)
i;
654 if (energy>=SLenergies.at(i))
return (
int)
i;
664 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindEtaBin can be called only after BeginOfEvent\n\n";
665 throw SimG4Exception(
"\n\nNULL Pointer to the shower library.\n\n");
668 if (eta>=SLetas.back())
return SLetas.size()-1;
670 for(;i<SLetas.size()-1;i++)
671 if (eta >= SLetas.at(i) && eta < SLetas.at(i+1))
return (
int)
i;
673 if (eta>=SLetas.at(i))
return (
int)
i;
685 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindPhiBin can be called only after BeginOfEvent\n\n";
686 throw SimG4Exception(
"\n\nNULL Pointer to the shower library.\n\n");
689 if (phi>=SLphis.back())
return SLphis.size()-1;
691 for(;i<SLphis.size()-1;i++)
692 if (phi >= SLphis.at(i) && phi < SLphis.at(i+1))
return (
int)
i;
694 if (phi>=SLphis.at(i))
return (
int)
i;
702 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nIsSLReady must be called when a new event starts.\n\n";
703 throw SimG4Exception(
"\n\nNOT NULL Pointer to the shower library.\n\n");
729 if (thePrim==0)
return;
735 if (pInit==0)
return;
736 double costheta = pz/pInit;
738 eta = -
log(
tan(theta/2.0));
739 phi = (px==0 && py==0) ? 0 : atan2(py,px);
744 px=py=pz=phi=eta=0.0;
745 if (thePrim==0)
return;
746 px = thePrim->GetMomentum().x()/
GeV;
747 py = thePrim->GetMomentum().y()/
GeV;
748 pz = thePrim->GetMomentum().z()/
GeV;
749 pInit = thePrim->GetMomentum().mag()/
GeV;
751 if (pInit==0)
return;
752 double costheta = pz/pInit;
754 eta = -
log(
tan(theta/2.0));
755 phi = (px==0 && py==0) ? 0 : atan2(py,px);
756 phi = thePrim->GetMomentum().phi();
763 std::vector<G4PrimaryParticle*>
thePrims;
764 G4PrimaryParticle* thePrim = 0;
765 G4int nvertex = evt->GetNumberOfPrimaryVertex();
766 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Event has " << nvertex <<
" vertex";
768 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"CastorShowerLibraryMaker::GetPrimary ERROR: no vertex";
772 for (
int i = 0 ;
i<nvertex;
i++) {
773 G4PrimaryVertex* avertex = evt->GetPrimaryVertex(
i);
776 <<
"CastorShowerLibraryMaker::GetPrimary ERROR: pointer to vertex = 0";
779 unsigned int npart = avertex->GetNumberOfParticle();
781 for (
unsigned int j=0;
j<
npart;
j++) {
785 thePrim=avertex->GetPrimary(trackID);
788 thePrims.push_back(thePrim);
796 edm::LogInfo(
"CastorShowerLibraryInfo") <<
"NULL shower pointer. Printing both";
797 std::cout <<
"Electromagnetic" << std::endl;
810 for(
int n=0;
n<11+(nBinsEta*nBinsPhi);
n++)
std::cout <<
"=";
812 for(
int i=0;
i<nBinsE;
i++) {
813 std::cout <<
"E bin " << std::setw(6) << SLenergies.at(
i) <<
" : ";
814 for(
int j=0;
j<nBinsEta;
j++) {
815 for(
int k=0;
k<nBinsPhi;
k++) {
822 if (ebin!=
i)
continue;
824 for(
int j=0;
j<nBinsEta;
j++) {
825 for(
int k=0;
k<nBinsPhi;
k++) {
832 for(
int n=0;
n<11+(nBinsEta*nBinsPhi);
n++)
std::cout <<
"=";
838 edm::LogInfo(
"CastorShowerLibraryMaker::SLacceptEvent:") <<
"Error. NULL pointer to CastorShowerEvent";
853 unsigned int volumeID=0;
854 double en_in_fi = 0.;
857 int nentries = theCAFI->entries();
867 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Error. NULL pointer to CastorShowerEvent";
877 for (
int ihit = 0; ihit < nentries; ihit++) {
882 <<
"Skipping hit from trackID " << hit_particleID;
889 int zside, sector, zmodule;
890 theCastorNumScheme->
unpackIndex(volumeID, zside, sector,zmodule);
894 <<
"\n side , sector , module = " << zside <<
" , "
895 << sector <<
" , " << zmodule
896 <<
"\n nphotons = " << hitEnergy ;
900 << theCastorNumScheme->
packIndex(zside, sector,zmodule);
904 <<
"\n nentries = " << nentries
905 <<
"\n time[" << ihit <<
"] = " << time
906 <<
"\n trackID[" << ihit <<
"] = " << aHit->
getTrackID()
907 <<
"\n volumeID[" << ihit <<
"] = " << volumeID
908 <<
"\n nphotons[" << ihit <<
"] = " << hitEnergy
909 <<
"\n side, sector, module = " << zside <<
", " << sector<<
", " << zmodule
910 <<
"\n packIndex " << theCastorNumScheme->
packIndex(zside,sector,zmodule)
911 <<
"\n X,Y,Z = " << entry.x() <<
","<< entry.y() <<
"," << entry.z();
925 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"No hits found for this track (trackID=" << ipart <<
")." << std::endl;
926 if (theCastorNumScheme)
delete theCastorNumScheme;
932 if (theCastorNumScheme)
delete theCastorNumScheme;
938 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinE can be called only after BeginOfEvent\n\n";
947 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinEta can be called only after BeginOfEvent\n\n";
956 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinPhi can be called only after BeginOfEvent\n\n";
964 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisEBinFilled can be called only after BeginOfEvent\n\n";
973 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisEtaBinFilled can be called only after BeginOfEvent\n\n";
982 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisPhiBinFilled can be called only after BeginOfEvent\n\n";
989 G4TrackVector *p_sec =
const_cast<G4TrackVector*
>(aStep->GetSecondary());
990 for(
int i=0;
i<int(p_sec->size());
i++) {
991 std::cout <<
"Killing track ID " << p_sec->at(
i)->GetTrackID() <<
" and its secondaries"
992 <<
" Produced by Process " << p_sec->at(
i)->GetCreatorProcess()->GetProcessName()
993 <<
" in the volume " << aStep->GetTrack()->GetVolume()->GetName()
995 p_sec->at(
i)->SetTrackStatus(fKillTrackAndSecondaries);
1003 for (
int ihit = 0; ihit < theCAFI->entries(); ihit++) {
1004 int id = (*theCAFI)[ihit]->getTrackID();
1005 tot_energy+=(*theCAFI)[ihit]->getEnergyDeposit();
1008 int particleType =
thePrims.at(
i)->GetPDGcode();
1010 hit_prim = particleType;
1013 std::cout <<
"Track ID " <<
id <<
" produced a hit which is not associated with a primary."
1015 miss_energy+=(*theCAFI)[ihit]->getEnergyDeposit();
std::string eventNtFileName
std::vector< double > SLEtaBins
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)
virtual ~CastorShowerLibraryMaker()
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)
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)
void update(const BeginOfJob *run)
This routine will be called when the appropriate signal arrives.
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
volatile std::atomic< bool > shutdown_flag false
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