28 #include "CLHEP/Units/GlobalSystemOfUnits.h"
29 #include "CLHEP/Units/GlobalPhysicalConstants.h"
42 DeActivatePhysicsProcess(
false),
80 std::cout <<
"============================================================================" << std::endl;
81 std::cout <<
"CastorShowerLibraryMaker:: Initialized as observer" << std::endl;
82 std::cout <<
" Event Ntuple will be created" << std::endl;
90 std::cout <<
"============================================================================" << std::endl;
124 showerholder.
nEvtInBinEta.assign(nBinsE, std::vector<int>(0));
126 for (
int i = 0;
i < nBinsE;
i++) {
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);
236 G4EventManager* e_mgr = G4EventManager::GetEventManager();
244 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
245 G4PrimaryParticle* thePrim =
thePrims.at(
i);
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;
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();
314 if (trk->GetCurrentStepNumber() == 1) {
315 if (trk->GetParentID() == 0) {
316 CurrentPrimary = (
int)trk->GetDynamicParticle()->GetPDGcode();
317 if (CurrentPrimary == 0)
318 SimG4Exception(
"CastorShowerLibraryMaker::update(G4Step) -> Primary particle undefined");
322 G4ProcessManager* p_mgr = trk->GetDefinition()->GetProcessManager();
323 G4ProcessVector* pvec = p_mgr->GetProcessList();
324 pvec_size = pvec->size();
325 for (
int i = 0;
i < pvec_size;
i++) {
326 G4VProcess*
proc = (*pvec)(
i);
327 if (
proc->GetProcessName() !=
"Transportation" &&
proc->GetProcessName() !=
"Decay") {
328 std::cout <<
"DeActivating process: " <<
proc->GetProcessName() << std::endl;
329 p_mgr->SetProcessActivation(
proc,
false);
336 double t =
std::abs((
pos.z() - trk->GetPosition().z())) / trk->GetVelocity();
337 double r = (
pos.z() - trk->GetPosition().z()) / trk->GetMomentum().cosTheta();
338 pos.setX(
r *
sin(trk->GetMomentum().theta()) *
cos(trk->GetMomentum().phi()) + trk->GetPosition().x());
339 pos.setY(
r *
sin(trk->GetMomentum().theta()) *
sin(trk->GetMomentum().phi()) + trk->GetPosition().y());
340 trk->SetPosition(
pos);
341 trk->SetGlobalTime(trk->GetGlobalTime() +
t);
342 trk->AddTrackLength(
r);
344 std::cout <<
"CastorShowerLibraryMaker::update(G4Step) -> Killing spurious track" << std::endl;
345 trk->SetTrackStatus(fKillTrackAndSecondaries);
351 std::string CurVolume = trk->GetVolume()->GetName();
356 CurVolume ==
"CAST")) {
361 G4ProcessManager* p_mgr = trk->GetDefinition()->GetProcessManager();
362 G4ProcessVector* pvec = p_mgr->GetProcessList();
363 pvec_size = pvec->size();
364 for (
int i = 0;
i < pvec_size;
i++) {
365 G4VProcess*
proc = (*pvec)(
i);
366 if (
proc->GetProcessName() !=
"Transportation" &&
proc->GetProcessName() !=
"Decay") {
367 std::cout <<
" Activating process: " <<
proc->GetProcessName() << std::endl;
368 p_mgr->SetProcessActivation(
proc,
true);
374 if (trk->GetMomentum().phi() >
MaxPhi || trk->GetMomentum().eta() >
MaxEta) {
375 trk->SetTrackStatus(fKillTrackAndSecondaries);
385 if (CurrentPrimary != 0 && trk->GetParentID() == 0 && !
InsideCastor) {
388 double pre_phi = aStep->GetPreStepPoint()->GetMomentum().phi();
389 double cur_phi = trk->GetMomentum().phi();
390 if (pre_phi != cur_phi) {
391 std::cout <<
"Primary track phi : " << pre_phi <<
" changed in current step: " << cur_phi
392 <<
" by processes:" << std::endl;
393 const G4VProcess*
proc = aStep->GetPreStepPoint()->GetProcessDefinedStep();
394 std::cout <<
" " <<
proc->GetProcessName() <<
" In volume " << CurVolume << std::endl;
415 if ((*evt)()->IsAborted()) {
416 std::cout <<
"\n========================================================================"
417 <<
"\nEndOfEvent: EVENT ABORTED"
418 <<
"\n========================================================================" << std::endl;
431 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"No valid primary particle found. Skipping event" << std::endl;
435 G4HCofThisEvent* allHC = (*evt)()->GetHCofThisEvent();
436 int CAFIid = G4SDManager::GetSDMpointer()->GetCollectionID(
"CastorFI");
439 edm::LogInfo(
"CastorShowerLibraryMaker") <<
" update(*evt) --> accessed all HC ";
440 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Found " << theCAFI->entries() <<
" hits in G4HitCollection";
441 if (theCAFI->entries() == 0) {
442 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n Empty G4HitCollection";
447 int NEvtAccepted = 0;
449 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
450 G4PrimaryParticle* thePrim =
thePrims.at(
i);
452 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"nullptr Pointer to the primary" << std::endl;
462 SLType =
"Electromagnetic";
467 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n Primary (thePrim) trackID is " << thePrim->GetTrackID() <<
"\n";
470 double px = 0.,
py = 0., pz = 0., pInit = 0.,
eta = 0.,
phi = 0.;
475 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Primary did not hit CASTOR" << std::endl;
485 <<
"Event not accepted for ebin=" <<
ebin <<
",etabin=" <<
etabin <<
",phibin=" <<
phibin <<
"(" << pInit
486 <<
"," <<
eta <<
"," <<
phi <<
")" << std::endl;
494 <<
"\n CastorShowerLibraryMaker::update(EndOfEvent * evt) - event #" << (*evt)()->GetEventID();
523 NHitInEvent += shower->
getNhit();
530 int thecafi_entries = theCAFI->entries();
531 if (NEvtAccepted ==
int(
thePrims.size()) && thecafi_entries != NHitInEvent) {
532 std::cout <<
"WARNING: Inconsistent Number of Hits -> Hits in collection: " << theCAFI->entries()
533 <<
" Hits in the showers: " << NHitInEvent << std::endl;
534 double miss_energy = 0;
535 double tot_energy = 0;
537 if (miss_energy > 0) {
538 std::cout <<
"Total missing energy: " << miss_energy <<
" for an incident energy: " << tot_energy << std::endl;
568 unsigned int ibine, ibineta, ibinphi, ievt;
569 unsigned int jbine, jbineta, jbinphi, jevt;
571 ibine = ibineta = ibinphi = ievt = jbine = jbineta = jbinphi = jevt = 0;
576 int maxEvtInTree =
std::max(nEMevt, nHadevt);
581 while (nEvtInTree < maxEvtInTree) {
622 if (nEvtInTree == 1) {
623 theTree->SetBranchStatus(
"emShowerLibInfo.",
false);
624 theTree->SetBranchStatus(
"hadShowerLibInfo.",
false);
629 throw SimG4Exception(
"\n\nNumber of needed trigger events reached in CastorShowerLibraryMaker\n\n");
637 theTree->Write(
"", TObject::kOverwrite);
638 std::cout <<
"CastorShowerLibraryMaker: Ntuple event written" << std::endl;
640 std::cout <<
"CastorShowerLibraryMaker: Event file closed" << std::endl;
654 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindEnergyBin can be called only after BeginOfEvent\n\n";
655 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
658 if (
energy >= SLenergies.back())
659 return SLenergies.size() - 1;
662 for (;
i < SLenergies.size() - 1;
i++)
667 if (
energy >= SLenergies.at(
i))
678 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindEtaBin can be called only after BeginOfEvent\n\n";
679 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
682 if (
eta >= SLetas.back())
683 return SLetas.size() - 1;
685 for (;
i < SLetas.size() - 1;
i++)
686 if (
eta >= SLetas.at(
i) &&
eta < SLetas.at(
i + 1))
689 if (
eta >= SLetas.at(
i))
702 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nFindPhiBin can be called only after BeginOfEvent\n\n";
703 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.\n\n");
706 if (
phi >= SLphis.back())
707 return SLphis.size() - 1;
709 for (;
i < SLphis.size() - 1;
i++)
710 if (
phi >= SLphis.at(
i) &&
phi < SLphis.at(
i + 1))
713 if (
phi >= SLphis.at(
i))
721 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nIsSLReady must be called when a new event starts.\n\n";
722 throw SimG4Exception(
"\n\nNOT nullptr Pointer to the shower library.\n\n");
747 int thePrim,
double&
px,
double&
py,
double& pz,
double& pInit,
double&
eta,
double&
phi) {
758 double costheta = pz / pInit;
765 G4PrimaryParticle* thePrim,
double&
px,
double&
py,
double& pz,
double& pInit,
double&
eta,
double&
phi) {
767 if (thePrim ==
nullptr)
769 px = thePrim->GetMomentum().x() /
GeV;
770 py = thePrim->GetMomentum().y() /
GeV;
771 pz = thePrim->GetMomentum().z() /
GeV;
772 pInit = thePrim->GetMomentum().mag() /
GeV;
776 double costheta = pz / pInit;
780 phi = thePrim->GetMomentum().phi();
786 std::vector<G4PrimaryParticle*>
thePrims;
787 G4PrimaryParticle* thePrim =
nullptr;
788 G4int nvertex = evt->GetNumberOfPrimaryVertex();
789 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Event has " << nvertex <<
" vertex";
791 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"CastorShowerLibraryMaker::GetPrimary ERROR: no vertex";
795 for (
int i = 0;
i < nvertex;
i++) {
796 G4PrimaryVertex* avertex = evt->GetPrimaryVertex(
i);
797 if (avertex ==
nullptr) {
798 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"CastorShowerLibraryMaker::GetPrimary ERROR: pointer to vertex = 0";
801 unsigned int npart = avertex->GetNumberOfParticle();
804 for (
unsigned int j = 0;
j <
npart;
j++) {
808 thePrim = avertex->GetPrimary(trackID);
821 edm::LogInfo(
"CastorShowerLibraryInfo") <<
"nullptr shower pointer. Printing both";
822 std::cout <<
"Electromagnetic" << std::endl;
838 for (
int i = 0;
i < nBinsE;
i++) {
839 std::cout <<
"E bin " << std::setw(6) << SLenergies.at(
i) <<
" : ";
867 edm::LogInfo(
"CastorShowerLibraryMaker::SLacceptEvent:") <<
"Error. nullptr pointer to CastorShowerEvent";
887 unsigned int volumeID = 0;
888 double en_in_fi = 0.;
891 int nentries = theCAFI->entries();
901 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Error. nullptr pointer to CastorShowerEvent";
911 for (
int ihit = 0; ihit < nentries; ihit++) {
916 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"Skipping hit from trackID " << hit_particleID;
923 int zside, sector, zmodule;
928 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n side , sector , module = " <<
zside <<
" , " << sector <<
" , "
929 << zmodule <<
"\n nphotons = " << hitEnergy;
933 <<
"\n packIndex = " << theCastorNumScheme->
packIndex(
zside, sector, zmodule);
937 <<
"\n nentries = " << nentries <<
"\n time[" << ihit <<
"] = " <<
time <<
"\n trackID[" << ihit
938 <<
"] = " << aHit->
getTrackID() <<
"\n volumeID[" << ihit <<
"] = " << volumeID <<
"\n nphotons[" << ihit
939 <<
"] = " << hitEnergy <<
"\n side, sector, module = " <<
zside <<
", " << sector <<
", " << zmodule
940 <<
"\n packIndex " << theCastorNumScheme->
packIndex(
zside, sector, zmodule) <<
"\n X,Y,Z = " <<
entry.x()
955 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"No hits found for this track (trackID=" << ipart <<
")." << std::endl;
956 if (theCastorNumScheme)
957 delete theCastorNumScheme;
963 if (theCastorNumScheme)
964 delete theCastorNumScheme;
969 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinE can be called only after BeginOfEvent\n\n";
970 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
977 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinEta can be called only after BeginOfEvent\n\n";
978 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
985 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLnEvtInBinPhi can be called only after BeginOfEvent\n\n";
986 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
992 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisEBinFilled can be called only after BeginOfEvent\n\n";
993 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1001 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisEtaBinFilled can be called only after BeginOfEvent\n\n";
1002 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1010 edm::LogInfo(
"CastorShowerLibraryMaker") <<
"\n\nSLisPhiBinFilled can be called only after BeginOfEvent\n\n";
1011 throw SimG4Exception(
"\n\nnullptr Pointer to the shower library.");
1018 const G4TrackVector* p_sec = aStep->GetSecondary();
1019 for (
int i = 0;
i <
int(p_sec->size());
i++) {
1020 std::cout <<
"Killing track ID " << p_sec->at(
i)->GetTrackID() <<
" and its secondaries"
1021 <<
" Produced by Process " << p_sec->at(
i)->GetCreatorProcess()->GetProcessName()
1022 <<
" in the volume " << aStep->GetTrack()->GetVolume()->GetName() << std::endl;
1023 p_sec->at(
i)->SetTrackStatus(fKillTrackAndSecondaries);
1031 int nhits = theCAFI->entries();
1032 for (
int ihit = 0; ihit <
nhits; ihit++) {
1033 int id = (*theCAFI)[ihit]->getTrackID();
1034 tot_energy += (*theCAFI)[ihit]->getEnergyDeposit();
1036 for (
unsigned int i = 0;
i <
thePrims.size();
i++) {
1041 if (hit_prim == 0) {
1042 std::cout <<
"Track ID " <<
id <<
" produced a hit which is not associated with a primary." << std::endl;
1043 miss_energy += (*theCAFI)[ihit]->getEnergyDeposit();