CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CastorShowerLibraryMaker.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: ShowerLibraryProducer
4 // Class : CastorShowerLibraryMaker
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: P. Katsas
10 // Created: 02/2007
11 //
12 // Adapted by W. Carvalho , 02/2009
13 //
15 
18 
24 
25 // Classes for shower library Root file
28 
37 
40 
42 
43 #include "G4RunManager.hh"
44 #include "G4SDManager.hh"
45 #include "G4Step.hh"
46 #include "G4Track.hh"
47 #include "G4Event.hh"
48 #include "G4PrimaryVertex.hh"
49 #include "G4VProcess.hh"
50 #include "G4HCofThisEvent.hh"
51 #include "G4UserEventAction.hh"
52 
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>
58 
59 #include "TROOT.h"
60 #include "TFile.h"
61 #include "TH1.h"
62 #include "TH2.h"
63 #include "TProfile.h"
64 #include "TNtuple.h"
65 #include "TRandom.h"
66 #include "TLorentzVector.h"
67 #include "TUnixSystem.h"
68 #include "TSystem.h"
69 #include "TMath.h"
70 #include "TF1.h"
71 
72 #include <cassert>
73 #include <cmath>
74 #include <cstdlib>
75 #include <iomanip>
76 #include <iostream>
77 #include <map>
78 #include <set>
79 #include <sstream>
80 #include <string>
81 #include <vector>
82 
83 typedef std::vector<std::vector<std::vector<std::vector<CastorShowerEvent> > > > SLBin3D; // bin in energy, eta and phi
84 
86  public Observer<const BeginOfJob*>,
87  public Observer<const BeginOfRun*>,
88  public Observer<const EndOfRun*>,
89  public Observer<const BeginOfEvent*>,
90  public Observer<const EndOfEvent*>,
91  public Observer<const G4Step*> {
92 public:
94  ~CastorShowerLibraryMaker() override;
95 
96 private:
97  typedef int ebin;
98  typedef int etabin;
99  typedef int phibin;
100  // private structures
101  struct ShowerLib {
103  SLBin3D SLCollection; // the showers
104  std::vector<double> SLEnergyBins;
105  std::vector<double> SLEtaBins;
106  std::vector<double> SLPhiBins;
107  unsigned int nEvtPerBinE;
108  unsigned int nEvtPerBinEta;
109  unsigned int nEvtPerBinPhi;
110  std::vector<int> nEvtInBinE;
111  std::vector<std::vector<int> > nEvtInBinEta;
112  std::vector<std::vector<std::vector<int> > > nEvtInBinPhi;
113  };
114 
115  // observer classes
116  void update(const BeginOfJob* run) override;
117  void update(const BeginOfRun* run) override;
118  void update(const EndOfRun* run) override;
119  void update(const BeginOfEvent* evt) override;
120  void update(const EndOfEvent* evt) override;
121  void update(const G4Step* step) override;
122 
123 private:
124  void Finish();
125 
126  // Job general parameters
129 
130  unsigned int NPGParticle; // number of particles requested to Particle Gun
131  std::vector<int> PGParticleIDs; //p. gun particle IDs
132  bool DoHadSL; // true if hadronic SL should be produced
133  bool DoEmSL; // true if electromag. SL should be produced
134  bool InsideCastor; // true if particle step inside CASTOR
135  bool DeActivatePhysicsProcess; //cfg parameter: True if phys. proc. should be off from IP to Castor
136  std::vector<G4PrimaryParticle*> thePrims; // list of primaries for this event
137 
138  // Pointers for user defined class objects to be stored to Root file
145  ShowerLib* SLShowerptr; // pointer to the current shower collection (above)
146  std::map<int, std::set<int> > MapOfSecondaries; // map to hold all secondaries ID keyed by
147  // the PDG code of the primary
148 
149  std::map<int, G4ThreeVector> PrimaryMomentum;
150  std::map<int, G4ThreeVector> PrimaryPosition;
151  double MaxEta; // limits the eta region, the lower limit is given by the SL bins
152  double MaxPhi; // limits the phi region, the lower limit is given by the SL bins
153  // private methods
154  int FindEnergyBin(double e);
155  int FindEtaBin(double eta);
156  int FindPhiBin(double phi);
157  bool SLacceptEvent(int, int, int);
158  bool IsSLReady();
159  void GetKinematics(G4PrimaryParticle*, double& px, double& py, double& pz, double& pInit, double& eta, double& phi);
160  void GetKinematics(int, double& px, double& py, double& pz, double& pInit, double& eta, double& phi);
161 
162  std::vector<G4PrimaryParticle*> GetPrimary(const G4Event*);
164  void InitSLHolder(ShowerLib&);
165 
166  void printSLstatus(int, int, int);
167  int& SLnEvtInBinE(int ebin);
168  int& SLnEvtInBinEta(int ebin, int etabin);
169  int& SLnEvtInBinPhi(int ebin, int etabin, int phibin);
170  bool SLisEBinFilled(int ebin);
171  bool SLisEtaBinFilled(int ebin, int etabin);
172  bool SLisPhiBinFilled(int ebin, int etabin, int phibin);
173  void KillSecondaries(const G4Step* step);
174  void GetMissingEnergy(CaloG4HitCollection*, double&, double&);
175 
176  // Root pointers
177  TFile* theFile;
178  TTree* theTree;
179 
181  int stepIndex; // ignore, please
182 };
183 
185  : NPGParticle(0),
186  DoHadSL(false),
187  DoEmSL(false),
188  DeActivatePhysicsProcess(false),
189  emShower(nullptr),
190  hadShower(nullptr) {
191  MapOfSecondaries.clear();
192  hadInfo = nullptr;
193  emInfo = nullptr;
194  edm::ParameterSet p_SLM = p.getParameter<edm::ParameterSet>("CastorShowerLibraryMaker");
195  verbosity = p_SLM.getParameter<int>("Verbosity");
196  eventNtFileName = p_SLM.getParameter<std::string>("EventNtupleFileName");
197  hadSLHolder.nEvtPerBinPhi = p_SLM.getParameter<int>("nhadEvents");
198  emSLHolder.nEvtPerBinPhi = p_SLM.getParameter<int>("nemEvents");
199  hadSLHolder.SLEnergyBins = p_SLM.getParameter<std::vector<double> >("SLhadEnergyBins");
200  hadSLHolder.SLEtaBins = p_SLM.getParameter<std::vector<double> >("SLhadEtaBins");
201  hadSLHolder.SLPhiBins = p_SLM.getParameter<std::vector<double> >("SLhadPhiBins");
202  emSLHolder.SLEnergyBins = p_SLM.getParameter<std::vector<double> >("SLemEnergyBins");
203  emSLHolder.SLEtaBins = p_SLM.getParameter<std::vector<double> >("SLemEtaBins");
204  emSLHolder.SLPhiBins = p_SLM.getParameter<std::vector<double> >("SLemPhiBins");
205  PGParticleIDs = p_SLM.getParameter<std::vector<int> >("PartID");
206  DeActivatePhysicsProcess = p_SLM.getParameter<bool>("DeActivatePhysicsProcess");
207  MaxPhi = p_SLM.getParameter<double>("SLMaxPhi");
208  MaxEta = p_SLM.getParameter<double>("SLMaxEta");
209  //
210  NPGParticle = PGParticleIDs.size();
211  for (unsigned int i = 0; i < PGParticleIDs.size(); i++) {
212  switch (std::abs(PGParticleIDs.at(i))) {
213  case 11:
214  case 22:
215  DoEmSL = true;
216  break;
217  default:
218  DoHadSL = true;
219  }
220  }
225 
226  std::cout << "============================================================================" << std::endl;
227  std::cout << "CastorShowerLibraryMaker:: Initialized as observer" << std::endl;
228  std::cout << " Event Ntuple will be created" << std::endl;
229  std::cout << " Event Ntuple file: " << eventNtFileName << std::endl;
230  std::cout << " Number of Hadronic events in E bins: " << hadSLHolder.nEvtPerBinE << std::endl;
231  std::cout << " Number of Hadronic events in Eta bins: " << hadSLHolder.nEvtPerBinEta << std::endl;
232  std::cout << " Number of Hadronic events in Phi bins: " << hadSLHolder.nEvtPerBinPhi << std::endl;
233  std::cout << " Number of Electromag. events in E bins: " << emSLHolder.nEvtPerBinE << std::endl;
234  std::cout << " Number of Electromag. events in Eta bins: " << emSLHolder.nEvtPerBinEta << std::endl;
235  std::cout << " Number of Electromag. events in Phi bins: " << emSLHolder.nEvtPerBinPhi << std::endl;
236  std::cout << "============================================================================" << std::endl;
237  std::cout << std::endl;
238 
239  // Initializing the SL collections
242 }
244  int nBinsE, nBinsEta, nBinsPhi, nEvtPerBinPhi;
245  nBinsE = showerholder.SLEnergyBins.size();
246  nBinsEta = showerholder.SLEtaBins.size();
247  nBinsPhi = showerholder.SLPhiBins.size();
248  nEvtPerBinPhi = showerholder.nEvtPerBinPhi;
249  //
250  // Info
251  //
252  showerholder.SLInfo.Energy.setNEvts(nEvtPerBinPhi * nBinsPhi * nBinsEta * nBinsE);
253  showerholder.SLInfo.Energy.setNEvtPerBin(nEvtPerBinPhi * nBinsPhi * nBinsEta);
254  showerholder.SLInfo.Energy.setNBins(nBinsE);
255  showerholder.SLInfo.Energy.setBin(showerholder.SLEnergyBins);
256  //
257  showerholder.SLInfo.Eta.setNEvts(nEvtPerBinPhi * nBinsPhi * nBinsEta);
258  showerholder.SLInfo.Eta.setNEvtPerBin(nEvtPerBinPhi * nBinsPhi);
259  showerholder.SLInfo.Eta.setNBins(nBinsEta);
260  showerholder.SLInfo.Eta.setBin(showerholder.SLEtaBins);
261  //
262  showerholder.SLInfo.Phi.setNEvts(nEvtPerBinPhi * nBinsPhi);
263  showerholder.SLInfo.Phi.setNEvtPerBin(nEvtPerBinPhi);
264  showerholder.SLInfo.Phi.setNBins(nBinsPhi);
265  showerholder.SLInfo.Phi.setBin(showerholder.SLPhiBins);
266  //
267  // Shower
268  showerholder.SLCollection.assign(nBinsE, std::vector<std::vector<std::vector<CastorShowerEvent> > >());
269  showerholder.nEvtInBinE.assign(nBinsE, 0);
270  showerholder.nEvtInBinEta.assign(nBinsE, std::vector<int>(0));
271  showerholder.nEvtInBinPhi.assign(nBinsE, std::vector<std::vector<int> >());
272  for (int i = 0; i < nBinsE; i++) {
273  showerholder.SLCollection.at(i).assign(nBinsEta, std::vector<std::vector<CastorShowerEvent> >());
274  showerholder.nEvtInBinEta.at(i).assign(nBinsEta, 0);
275  showerholder.nEvtInBinPhi.at(i).assign(nBinsEta, std::vector<int>(0));
276  for (int j = 0; j < nBinsEta; j++) {
277  showerholder.SLCollection.at(i).at(j).assign(nBinsPhi, std::vector<CastorShowerEvent>());
278  showerholder.nEvtInBinPhi.at(i).at(j).assign(nBinsPhi, 0);
279  for (int k = 0; k < nBinsPhi; k++)
280  showerholder.SLCollection.at(i).at(j).at(k).assign(nEvtPerBinPhi, CastorShowerEvent());
281  }
282  }
283 }
284 
285 //===============================================================================================
286 
288  Finish();
289 
290  std::cout << "CastorShowerLibraryMaker: End of process" << std::endl;
291 }
292 
293 //=================================================================== per EVENT
295  std::cout << " CastorShowerLibraryMaker::Starting new job " << std::endl;
296 }
297 
298 //==================================================================== per RUN
300  std::cout << std::endl << "CastorShowerLibraryMaker: Starting Run" << std::endl;
301 
302  std::cout << "CastorShowerLibraryMaker: output event root file created" << std::endl;
303 
304  TString eventfilename = eventNtFileName;
305  theFile = new TFile(eventfilename, "RECREATE");
306  theTree = new TTree("CastorCherenkovPhotons", "Cherenkov Photons");
307 
308  Int_t split = 1;
309  Int_t bsize = 64000;
311  emShower = new CastorShowerEvent();
314  // Create Branchs
315  theTree->Branch("emShowerLibInfo.", "CastorShowerLibraryInfo", &emInfo, bsize, split);
316  theTree->Branch("emParticles.", "CastorShowerEvent", &emShower, bsize, split);
317  theTree->Branch("hadShowerLibInfo.", "CastorShowerLibraryInfo", &hadInfo, bsize, split);
318  theTree->Branch("hadParticles.", "CastorShowerEvent", &hadShower, bsize, split);
319 
320  // set the Info for electromagnetic shower
321  // set the energy bins info
326  // set the eta bins info
331  // set the eta bins info
336  // The same for the hadronic shower
337  // set the energy bins info
342  // set the eta bins info
347  // set the eta bins info
352  // int flag = theTree->GetBranch("CastorShowerLibInfo")->Fill();
353  // Loop on all leaves of this branch to fill Basket buffer.
354  // The function returns the number of bytes committed to the memory basket.
355  // If a write error occurs, the number of bytes returned is -1.
356  // If no data are written, because e.g. the branch is disabled,
357  // the number of bytes returned is 0.
358  // if(flag==-1) {
359  // edm::LogVerbatim("CastorAnalyzer") << " WARNING: Error writing to Branch \"CastorShowerLibInfo\" \n" ;
360  // } else
361  // if(flag==0) {
362  // edm::LogVerbatim("CastorAnalyzer") << " WARNING: No data written to Branch \"CastorShowerLibInfo\" \n" ;
363  // }
364 
365  // Initialize "accounting" variables
366 
367  eventIndex = 0;
368 }
369 
370 //=================================================================== per EVENT
372  eventIndex++;
373  stepIndex = 0;
374  InsideCastor = false;
375  PrimaryMomentum.clear();
376  PrimaryPosition.clear();
377  int NAccepted = 0;
378  // reset the pointers to the shower objects
379  SLShowerptr = nullptr;
380  MapOfSecondaries.clear();
381  thePrims.clear();
382  G4EventManager* e_mgr = G4EventManager::GetEventManager();
383  if (IsSLReady()) {
384  printSLstatus(-1, -1, -1);
385  update((EndOfRun*)nullptr);
386  return;
387  }
388 
389  thePrims = GetPrimary((*evt)());
390  for (unsigned int i = 0; i < thePrims.size(); i++) {
391  G4PrimaryParticle* thePrim = thePrims.at(i);
392  int particleType = thePrim->GetPDGcode();
393 
394  std::string SLType("");
395  if (particleType == 11) {
397  SLType = "Electromagnetic";
398  } else {
400  SLType = "Hadronic";
401  }
402  double px = 0., py = 0., pz = 0., pInit = 0., eta = 0., phi = 0.;
403  GetKinematics(thePrim, px, py, pz, pInit, eta, phi);
404  int ebin = FindEnergyBin(pInit);
405  int etabin = FindEtaBin(eta);
406  int phibin = FindPhiBin(phi);
407  if (verbosity)
408  std::cout << "\n========================================================================"
409  << "\nBeginOfEvent: E : " << pInit << "\t bin : " << ebin << "\n Eta : " << eta
410  << "\t bin : " << etabin << "\n Phi : " << phi << "\t bin : " << phibin
411  << "\n========================================================================" << std::endl;
412 
413  if (ebin < 0 || etabin < 0 || phibin < 0)
414  continue;
415  bool accept = false;
416  if (!(SLacceptEvent(ebin, etabin, phibin))) {
417  /*
418 // To increase the chance of a particle arriving at CASTOR inside a not full bin,
419 // check if there is available phase space in the neighboring bins
420  unsigned int ebin_min = std::max(0,ebin-3);
421  unsigned int eta_bin_min = std::max(0,etabin-2);
422  unsigned int eta_bin_max = std::min(etabin,etabin+2);
423  unsigned int phi_bin_min = std::max(0,phibin-2);
424  unsigned int phi_bin_max = std::min(phibin,phibin+2);
425  for(unsigned int i_ebin=ebin_min;i_ebin<=(unsigned int)ebin;i_ebin++) {
426  for (unsigned int i_etabin=eta_bin_min;i_etabin<=eta_bin_max;i_etabin++) {
427  for (unsigned int i_phibin=phi_bin_min;i_phibin<=phi_bin_max;i_phibin++) {
428  if (SLacceptEvent((int)i_ebin,(int)i_etabin,(int)i_phibin)) {accept=true;break;}
429  }
430  if (accept) break;
431  }
432  if (accept) break;
433  }
434 */
435  if (!accept)
436  edm::LogVerbatim("CastorShowerLibraryMaker")
437  << "Event not accepted for ebin=" << ebin << ",etabin=" << etabin << ",phibin=" << phibin << std::endl;
438  } else {
439  accept = true;
440  }
441  if (accept)
442  NAccepted++;
443  }
444 
445  if (NAccepted == 0) {
446  const_cast<G4Event*>((*evt)())->SetEventAborted();
447  const_cast<G4Event*>((*evt)())->KeepTheEvent((G4bool) false);
448  e_mgr->AbortCurrentEvent();
449  }
450  SLShowerptr = nullptr;
451  //
452  std::cout << "CastorShowerLibraryMaker: Processing Event Number: " << eventIndex << std::endl;
453 }
454 
455 //=================================================================== per STEP
456 void CastorShowerLibraryMaker::update(const G4Step* aStep) {
457  static thread_local int CurrentPrimary = 0;
458  G4Track* trk = aStep->GetTrack();
459  int pvec_size;
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");
465  InsideCastor = false;
466  // Deactivate the physics process
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") {
474  std::cout << "DeActivating process: " << proc->GetProcessName() << std::endl;
475  p_mgr->SetProcessActivation(proc, false);
476  }
477  }
478  }
479  // move track to z of CASTOR
480  G4ThreeVector pos;
481  pos.setZ(-14390);
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);
489  } else if (!InsideCastor) {
490  std::cout << "CastorShowerLibraryMaker::update(G4Step) -> Killing spurious track" << std::endl;
491  trk->SetTrackStatus(fKillTrackAndSecondaries);
492  return;
493  }
494  MapOfSecondaries[CurrentPrimary].insert((int)trk->GetTrackID());
495  }
496  // Checks if primary already inside CASTOR
497  std::string CurVolume = trk->GetVolume()->GetName();
498  if (!InsideCastor && (
499  //CurVolume=="C3EF"||CurVolume=="C4EF"||CurVolume=="CAEL"||
500  //CurVolume=="CAHL"||CurVolume=="C3HF"||CurVolume=="C4HF")) {
501  //CurVolume=="CastorB"||
502  CurVolume == "CAST")) {
503  //CurVolume=="CAIR")) {
504  InsideCastor = true;
505  // Activate the physics process
506  if (trk->GetParentID() == 0 && DeActivatePhysicsProcess) {
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") {
513  std::cout << " Activating process: " << proc->GetProcessName() << std::endl;
514  p_mgr->SetProcessActivation(proc, true);
515  }
516  }
517  }
518  //PrimaryMomentum[CurrentPrimary]=aStep->GetPreStepPoint()->GetMomentum();
519  // check fiducial eta and phi
520  if (trk->GetMomentum().phi() > MaxPhi || trk->GetMomentum().eta() > MaxEta) {
521  trk->SetTrackStatus(fKillTrackAndSecondaries);
522  InsideCastor = false;
523  return;
524  }
525  PrimaryMomentum[CurrentPrimary] = trk->GetMomentum();
526  PrimaryPosition[CurrentPrimary] = trk->GetPosition();
527  KillSecondaries(aStep);
528  return;
529  }
530  // Kill the secondaries if they have been produced before entering castor
531  if (CurrentPrimary != 0 && trk->GetParentID() == 0 && !InsideCastor) {
532  KillSecondaries(aStep);
533  if (verbosity) {
534  double pre_phi = aStep->GetPreStepPoint()->GetMomentum().phi();
535  double cur_phi = trk->GetMomentum().phi();
536  if (pre_phi != cur_phi) {
537  std::cout << "Primary track phi : " << pre_phi << " changed in current step: " << cur_phi
538  << " by processes:" << std::endl;
539  const G4VProcess* proc = aStep->GetPreStepPoint()->GetProcessDefinedStep();
540  std::cout << " " << proc->GetProcessName() << " In volume " << CurVolume << std::endl;
541  }
542  }
543  }
544 
545  //==============================================
546  /*
547 */
548  /*
549  if(aStep->IsFirstStepInVolume()) {
550  edm::LogVerbatim("CastorShowerLibraryMaker") << "CastorShowerLibraryMaker::update(const G4Step * aStep):"
551  << "\n IsFirstStepInVolume , "
552  << "time = " << aStep->GetTrack()->GetGlobalTime() ;
553  }
554  stepIndex++;
555 */
556 }
557 
558 //================= End of EVENT ===============
560  // check if the job is done!
561  if ((*evt)()->IsAborted()) {
562  std::cout << "\n========================================================================"
563  << "\nEndOfEvent: EVENT ABORTED"
564  << "\n========================================================================" << std::endl;
565  return;
566  }
567  //DynamicRangeFlatRandomEGunProducer* pgun = edm::DynamicRangeFlatRandomEGunKernel::get_instance();
568  //std::cout << pgun->EGunMaxE() << std::endl;
569  /*
570  std::cout << "Minimum energy in Particle Gun : " << pgun->EGunMinE() << "\n"
571  << "Maximum energy in Particle Gun : " << pgun->EGunMaxE() << std::endl;
572 */
573  if (verbosity)
574  std::cout << "CastorShowerLibraryMaker: End of Event: " << eventIndex << std::endl;
575  // Get the pointer to the primary particle
576  if (thePrims.empty()) {
577  edm::LogVerbatim("CastorShowerLibraryMaker") << "No valid primary particle found. Skipping event" << std::endl;
578  return;
579  }
580  // access to the G4 hit collections
581  G4HCofThisEvent* allHC = (*evt)()->GetHCofThisEvent();
582  int CAFIid = G4SDManager::GetSDMpointer()->GetCollectionID("CastorFI");
583  CaloG4HitCollection* theCAFI = (CaloG4HitCollection*)allHC->GetHC(CAFIid);
584  if (verbosity)
585  edm::LogVerbatim("CastorShowerLibraryMaker") << " update(*evt) --> accessed all HC ";
586  edm::LogVerbatim("CastorShowerLibraryMaker") << "Found " << theCAFI->entries() << " hits in G4HitCollection";
587  if (theCAFI->entries() == 0) {
588  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n Empty G4HitCollection";
589  return;
590  }
591 
592  // Loop over primaries
593  int NEvtAccepted = 0;
594  int NHitInEvent = 0;
595  for (unsigned int i = 0; i < thePrims.size(); i++) {
596  G4PrimaryParticle* thePrim = thePrims.at(i);
597  if (!thePrim) {
598  edm::LogVerbatim("CastorShowerLibraryMaker") << "nullptr Pointer to the primary" << std::endl;
599  continue;
600  }
601  // Check primary particle type
602  int particleType = thePrim->GetPDGcode();
603 
604  // set the pointer to the shower collection
605  std::string SLType("");
606  if (particleType == 11) {
608  SLType = "Electromagnetic";
609  } else {
611  SLType = "Hadronic";
612  }
613  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n Primary (thePrim) trackID is " << thePrim->GetTrackID() << "\n";
614 
615  // Obtain primary particle's initial momentum (pInit)
616  double px = 0., py = 0., pz = 0., pInit = 0., eta = 0., phi = 0.;
617  GetKinematics(particleType, px, py, pz, pInit, eta, phi);
618  // Check if current event falls into any bin
619  // first: energy
620  if (pInit == 0) {
621  edm::LogVerbatim("CastorShowerLibraryMaker") << "Primary did not hit CASTOR" << std::endl;
622  continue;
623  }
624  int ebin = FindEnergyBin(pInit);
625  int etabin = FindEtaBin(eta);
626  int phibin = FindPhiBin(phi);
627  std::cout << SLType << std::endl;
628  printSLstatus(ebin, etabin, phibin);
629  if (!SLacceptEvent(ebin, etabin, phibin)) {
630  edm::LogVerbatim("CastorShowerLibraryMaker")
631  << "Event not accepted for ebin=" << ebin << ",etabin=" << etabin << ",phibin=" << phibin << "(" << pInit
632  << "," << eta << "," << phi << ")" << std::endl;
633  continue;
634  }
635  //
636  // event passed. Fill the vector accordingly
637  //
638  // Look for the Hit Collection
639  edm::LogVerbatim("CastorShowerLibraryMaker")
640  << "\n CastorShowerLibraryMaker::update(EndOfEvent * evt) - event #" << (*evt)()->GetEventID();
641 
642  /*
643  std::cout << "Number of collections : " << allHC->GetNumberOfCollections() << std::endl;
644  for(int ii = 0;ii<allHC->GetNumberOfCollections();ii++)
645  std::cout << "Name of collection " << ii << " : " << allHC->GetHC(ii)->GetName() << std::endl;
646 */
647 
648  CastorShowerEvent* shower = nullptr;
649  int cur_evt_idx = SLShowerptr->nEvtInBinPhi.at(ebin).at(etabin).at(phibin);
650  shower = &(SLShowerptr->SLCollection.at(ebin).at(etabin).at(phibin).at(cur_evt_idx));
651 
652  // Get Hit information
653  if (FillShowerEvent(theCAFI, shower, particleType)) {
654  // Primary particle information
655  /*
656  edm::LogVerbatim("CastorShowerLibraryMaker") << "New SL event: Primary = " << particleType
657  << "; Energy = " << pInit << "; Eta = " << eta << "; Phi = " << phi
658  << "; Nhits = " << shower->getNhit() << std::endl;
659 */
660  shower->setPrimE(pInit);
661  shower->setPrimEta(eta);
662  shower->setPrimPhi(phi);
663  shower->setPrimX(PrimaryPosition[particleType].x());
664  shower->setPrimY(PrimaryPosition[particleType].y());
665  shower->setPrimZ(PrimaryPosition[particleType].z());
666  SLnEvtInBinE(ebin)++;
667  SLnEvtInBinEta(ebin, etabin)++;
668  SLnEvtInBinPhi(ebin, etabin, phibin)++;
669  NHitInEvent += shower->getNhit();
670  NEvtAccepted++;
671  } else {
672  shower->Clear();
673  }
674  }
675  // Check for unassociated energy
676  int thecafi_entries = theCAFI->entries();
677  if (NEvtAccepted == int(thePrims.size()) && thecafi_entries != NHitInEvent) {
678  std::cout << "WARNING: Inconsistent Number of Hits -> Hits in collection: " << theCAFI->entries()
679  << " Hits in the showers: " << NHitInEvent << std::endl;
680  double miss_energy = 0;
681  double tot_energy = 0;
682  GetMissingEnergy(theCAFI, miss_energy, tot_energy);
683  if (miss_energy > 0) {
684  std::cout << "Total missing energy: " << miss_energy << " for an incident energy: " << tot_energy << std::endl;
685  }
686  }
687 
688  /*
689  for (int i=emSLHolder.SLEnergyBins.size()-1;i>0;i--) {
690  if (emSLHolder.nEvtInBinE.at(i)==(int)emSLHolder.nEvtPerBinE) {
691  std::ostringstream out;
692  out << emSLHolder.SLEnergyBins.at(i);
693  cout << "Bin Limit: " << out.str() << std::endl;
694  setenv("CASTOR_SL_PG_MAXE",out.str().c_str(),1);
695  }
696  break;
697  }
698 */
699  //int iEvt = (*evt)()->GetEventID();
700  //double xint;
701  /*
702  if (modf(log10(iEvt),&xint)==0)
703  std::cout << " CastorShowerLibraryMaker Event " << iEvt << std::endl;
704 */
705  // std::cout << std::endl << "===>>> Done writing user histograms " << std::endl;
706 }
707 
708 //========================= End of RUN ======================
710  // Fill the tree with the collected objects
711  if (!IsSLReady())
712  SimG4Exception("\n\nShower Library NOT READY.\n\n");
713 
714  unsigned int ibine, ibineta, ibinphi, ievt; // indexes for em shower
715  unsigned int jbine, jbineta, jbinphi, jevt; // indexes for had shower
716 
717  ibine = ibineta = ibinphi = ievt = jbine = jbineta = jbinphi = jevt = 0;
718 
719  int nEvtInTree = 0;
720  int nEMevt = emSLHolder.nEvtPerBinE * emSLHolder.SLEnergyBins.size();
721  int nHadevt = hadSLHolder.nEvtPerBinE * hadSLHolder.SLEnergyBins.size();
722  int maxEvtInTree = std::max(nEMevt, nHadevt);
723 
726 
727  while (nEvtInTree < maxEvtInTree) {
728  if (emShower)
729  emShower->Clear();
730  if (hadShower)
731  hadShower->Clear();
732  while (ibine < emSLHolder.SLEnergyBins.size() && nEMevt > 0) {
733  emShower = &(emSLHolder.SLCollection.at(ibine).at(ibineta).at(ibinphi).at(ievt));
734  ievt++;
735  if (ievt == emSLHolder.nEvtPerBinPhi) {
736  ievt = 0;
737  ibinphi++;
738  }
739  if (ibinphi == emSLHolder.SLPhiBins.size()) {
740  ibinphi = 0;
741  ibineta++;
742  }
743  if (ibineta == emSLHolder.SLEtaBins.size()) {
744  ibineta = 0;
745  ibine++;
746  }
747  break;
748  }
749  while (jbine < hadSLHolder.SLEnergyBins.size() && nHadevt > 0) {
750  hadShower = &(hadSLHolder.SLCollection.at(jbine).at(jbineta).at(jbinphi).at(jevt));
751  jevt++;
752  if (jevt == hadSLHolder.nEvtPerBinPhi) {
753  jevt = 0;
754  jbinphi++;
755  }
756  if (jbinphi == hadSLHolder.SLPhiBins.size()) {
757  jbinphi = 0;
758  jbineta++;
759  }
760  if (jbineta == hadSLHolder.SLEtaBins.size()) {
761  jbineta = 0;
762  jbine++;
763  }
764  break;
765  }
766  theTree->Fill();
767  nEvtInTree++;
768  if (nEvtInTree == 1) {
769  theTree->SetBranchStatus("emShowerLibInfo.", false);
770  theTree->SetBranchStatus("hadShowerLibInfo.", false);
771  }
772  }
773  // check if run is nullptr and exit
774  if (run == nullptr)
775  throw SimG4Exception("\n\nNumber of needed trigger events reached in CastorShowerLibraryMaker\n\n");
776 }
777 
778 //============================================================
780  // if (doNTcastorevent) {
781 
782  theFile->cd();
783  theTree->Write("", TObject::kOverwrite);
784  std::cout << "CastorShowerLibraryMaker: Ntuple event written" << std::endl;
785  theFile->Close();
786  std::cout << "CastorShowerLibraryMaker: Event file closed" << std::endl;
787 
788  // Delete pointers to objects, now that TTree has been written and TFile closed
789  // delete info;
790  // delete emShower;
791  // delete hadShower;
792  // }
793 }
795  //
796  // returns the integer index of the energy bin, taken from SLenergies vector
797  // returns -1 if ouside valid range
798  //
799  if (!SLShowerptr) {
800  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nFindEnergyBin can be called only after BeginOfEvent\n\n";
801  throw SimG4Exception("\n\nnullptr Pointer to the shower library.\n\n");
802  }
803  const std::vector<double>& SLenergies = SLShowerptr->SLEnergyBins;
804  if (energy >= SLenergies.back())
805  return SLenergies.size() - 1;
806 
807  unsigned int i = 0;
808  for (; i < SLenergies.size() - 1; i++)
809  if (energy >= SLenergies.at(i) && energy < SLenergies.at(i + 1))
810  return (int)i;
811 
812  // now i points to the last but 1 bin
813  if (energy >= SLenergies.at(i))
814  return (int)i;
815  // energy outside bin range
816  return -1;
817 }
819  //
820  // returns the integer index of the eta bin, taken from SLetas vector
821  // returns -1 if ouside valid range
822  //
823  if (!SLShowerptr) {
824  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nFindEtaBin can be called only after BeginOfEvent\n\n";
825  throw SimG4Exception("\n\nnullptr Pointer to the shower library.\n\n");
826  }
827  const std::vector<double>& SLetas = SLShowerptr->SLEtaBins;
828  if (eta >= SLetas.back())
829  return SLetas.size() - 1;
830  unsigned int i = 0;
831  for (; i < SLetas.size() - 1; i++)
832  if (eta >= SLetas.at(i) && eta < SLetas.at(i + 1))
833  return (int)i;
834  // now i points to the last but 1 bin
835  if (eta >= SLetas.at(i))
836  return (int)i;
837  // eta outside bin range
838  return -1;
839 }
841  //
842  // returns the integer index of the phi bin, taken from SLphis vector
843  // returns -1 if ouside valid range
844  //
845  // needs protection in case phi is outside range -pi,pi
846  //
847  if (!SLShowerptr) {
848  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nFindPhiBin can be called only after BeginOfEvent\n\n";
849  throw SimG4Exception("\n\nnullptr Pointer to the shower library.\n\n");
850  }
851  const std::vector<double>& SLphis = SLShowerptr->SLPhiBins;
852  if (phi >= SLphis.back())
853  return SLphis.size() - 1;
854  unsigned int i = 0;
855  for (; i < SLphis.size() - 1; i++)
856  if (phi >= SLphis.at(i) && phi < SLphis.at(i + 1))
857  return (int)i;
858  // now i points to the last but 1 bin
859  if (phi >= SLphis.at(i))
860  return (int)i;
861  // phi outside bin range
862  return -1;
863 }
865  // at this point, the pointer to the shower library should be nullptr
866  if (SLShowerptr) {
867  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nIsSLReady must be called when a new event starts.\n\n";
868  throw SimG4Exception("\n\nNOT nullptr Pointer to the shower library.\n\n");
869  }
870  // it is enough to check if all the energy bin is filled
871  if (DoEmSL) {
873  for (unsigned int i = 0; i < SLShowerptr->SLEnergyBins.size(); i++) {
874  if (!SLisEBinFilled(i)) {
875  SLShowerptr = nullptr;
876  return false;
877  }
878  }
879  }
880  if (DoHadSL) {
882  for (unsigned int i = 0; i < SLShowerptr->SLEnergyBins.size(); i++) {
883  if (!SLisEBinFilled(i)) {
884  SLShowerptr = nullptr;
885  return false;
886  }
887  }
888  }
889  SLShowerptr = nullptr;
890  return true;
891 }
893  int thePrim, double& px, double& py, double& pz, double& pInit, double& eta, double& phi) {
894  if (thePrim == 0)
895  return;
896  if (PrimaryMomentum.find(thePrim) == PrimaryMomentum.end())
897  return;
898  px = PrimaryMomentum[thePrim].x() / GeV;
899  py = PrimaryMomentum[thePrim].y() / GeV;
900  pz = PrimaryMomentum[thePrim].z() / GeV;
901  pInit = PrimaryMomentum[thePrim].mag() / GeV;
902  if (pInit == 0)
903  return;
904  double costheta = pz / pInit;
905  double theta = acos(std::min(std::max(costheta, double(-1.)), double(1.)));
906  eta = -log(tan(theta / 2.0));
907  phi = (px == 0 && py == 0) ? 0 : atan2(py, px); // the recommended way of calculating phi
908  phi = PrimaryMomentum[thePrim].phi();
909 }
911  G4PrimaryParticle* thePrim, double& px, double& py, double& pz, double& pInit, double& eta, double& phi) {
912  px = py = pz = phi = eta = 0.0;
913  if (thePrim == nullptr)
914  return;
915  px = thePrim->GetMomentum().x() / GeV;
916  py = thePrim->GetMomentum().y() / GeV;
917  pz = thePrim->GetMomentum().z() / GeV;
918  pInit = thePrim->GetMomentum().mag() / GeV;
919  //pInit = sqrt(pow(px,2.)+pow(py,2.)+pow(pz,2.));
920  if (pInit == 0)
921  return;
922  double costheta = pz / pInit;
923  double theta = acos(std::min(std::max(costheta, double(-1.)), double(1.)));
924  eta = -log(tan(theta / 2.0));
925  phi = (px == 0 && py == 0) ? 0 : atan2(py, px); // the recommended way of calculating phi
926  phi = thePrim->GetMomentum().phi();
927  //if (px!=0) phi=atan(py/px);
928 }
929 std::vector<G4PrimaryParticle*> CastorShowerLibraryMaker::GetPrimary(const G4Event* evt) {
930  // Find Primary info:
931  int trackID = 0;
932  std::vector<G4PrimaryParticle*> thePrims;
933  G4PrimaryParticle* thePrim = nullptr;
934  G4int nvertex = evt->GetNumberOfPrimaryVertex();
935  edm::LogVerbatim("CastorShowerLibraryMaker") << "Event has " << nvertex << " vertex";
936  if (nvertex != 1) {
937  edm::LogVerbatim("CastorShowerLibraryMaker") << "CastorShowerLibraryMaker::GetPrimary ERROR: no vertex";
938  return thePrims;
939  }
940 
941  for (int i = 0; i < nvertex; i++) {
942  G4PrimaryVertex* avertex = evt->GetPrimaryVertex(i);
943  if (avertex == nullptr) {
944  edm::LogVerbatim("CastorShowerLibraryMaker")
945  << "CastorShowerLibraryMaker::GetPrimary ERROR: pointer to vertex = 0";
946  continue;
947  }
948  unsigned int npart = avertex->GetNumberOfParticle();
949  if (npart != NPGParticle)
950  continue;
951  for (unsigned int j = 0; j < npart; j++) {
952  unsigned int k = 0;
953  //int test_pID = 0;
954  trackID = j;
955  thePrim = avertex->GetPrimary(trackID);
956  while (k < NPGParticle && PGParticleIDs.at(k++) != thePrim->GetPDGcode()) {
957  ;
958  };
959  if (k > NPGParticle)
960  continue; // ID not found in the requested particles
961  thePrims.push_back(thePrim);
962  }
963  }
964  return thePrims;
965 }
967  if (!SLShowerptr) {
968  edm::LogVerbatim("CastorShowerLibraryInfo") << "nullptr shower pointer. Printing both";
969  std::cout << "Electromagnetic" << std::endl;
971  this->printSLstatus(ebin, etabin, phibin);
972  std::cout << "Hadronic" << std::endl;
974  this->printSLstatus(ebin, etabin, phibin);
975  SLShowerptr = nullptr;
976  return;
977  }
978  int nBinsE = SLShowerptr->SLEnergyBins.size();
979  int nBinsEta = SLShowerptr->SLEtaBins.size();
980  int nBinsPhi = SLShowerptr->SLPhiBins.size();
981  std::vector<double> SLenergies = SLShowerptr->SLEnergyBins;
982  for (int n = 0; n < 11 + (nBinsEta * nBinsPhi); n++)
983  std::cout << "=";
984  std::cout << std::endl;
985  for (int i = 0; i < nBinsE; i++) {
986  std::cout << "E bin " << std::setw(6) << SLenergies.at(i) << " : ";
987  for (int j = 0; j < nBinsEta; j++) {
988  for (int k = 0; k < nBinsPhi; k++) {
989  (SLisPhiBinFilled(i, j, k)) ? std::cout << "1" : std::cout << "-";
990  }
991  if (j < nBinsEta - 1)
992  std::cout << "|";
993  }
994  std::cout << " (" << SLnEvtInBinE(i) << " events)";
995  std::cout << std::endl;
996  if (ebin != i)
997  continue;
998  std::cout << " ";
999  for (int j = 0; j < nBinsEta; j++) {
1000  for (int k = 0; k < nBinsPhi; k++) {
1001  (ebin == i && etabin == j && phibin == k) ? std::cout << "^" : std::cout << " ";
1002  }
1003  if (j < nBinsEta - 1)
1004  std::cout << " ";
1005  }
1006  std::cout << std::endl;
1007  }
1008  for (int n = 0; n < 11 + (nBinsEta * nBinsPhi); n++)
1009  std::cout << "=";
1010  std::cout << std::endl;
1011 }
1013  if (SLShowerptr == nullptr) {
1014  edm::LogVerbatim("CastorShowerLibraryMaker::SLacceptEvent:") << "Error. nullptr pointer to CastorShowerEvent";
1015  return false;
1016  }
1017  if (ebin < 0 || ebin >= int(SLShowerptr->SLEnergyBins.size()))
1018  return false;
1019  if (SLisEBinFilled(ebin))
1020  return false;
1021 
1022  if (etabin < 0 || etabin >= int(SLShowerptr->SLEtaBins.size()))
1023  return false;
1024  if (SLisEtaBinFilled(ebin, etabin))
1025  return false;
1026 
1027  if (phibin < 0 || phibin >= int(SLShowerptr->SLPhiBins.size()))
1028  return false;
1029  if (SLisPhiBinFilled(ebin, etabin, phibin))
1030  return false;
1031  return true;
1032 }
1034  unsigned int volumeID = 0;
1035  double en_in_fi = 0.;
1036  //double totalEnergy = 0;
1037 
1038  int nentries = theCAFI->entries();
1039 
1040  // Compute Total Energy in CastorFI volume
1041  /*
1042  for(int ihit = 0; ihit < nentries; ihit++) {
1043  CaloG4Hit* aHit = (*theCAFI)[ihit];
1044  totalEnergy += aHit->getEnergyDeposit();
1045  }
1046 */
1047  if (!shower) {
1048  edm::LogVerbatim("CastorShowerLibraryMaker") << "Error. nullptr pointer to CastorShowerEvent";
1049  return false;
1050  }
1051 
1052  CastorNumberingScheme* theCastorNumScheme = new CastorNumberingScheme();
1053  // Hit position
1056  int nHits;
1057  nHits = 0;
1058  for (int ihit = 0; ihit < nentries; ihit++) {
1059  CaloG4Hit* aHit = (*theCAFI)[ihit];
1060  int hit_particleID = aHit->getTrackID();
1061  if (MapOfSecondaries[ipart].find(hit_particleID) == MapOfSecondaries[ipart].end()) {
1062  if (verbosity)
1063  edm::LogVerbatim("CastorShowerLibraryMaker") << "Skipping hit from trackID " << hit_particleID;
1064  continue;
1065  }
1066  volumeID = aHit->getUnitID();
1067  double hitEnergy = aHit->getEnergyDeposit();
1068  en_in_fi += aHit->getEnergyDeposit();
1069  float time = aHit->getTimeSlice();
1070  int zside, sector, zmodule;
1071  theCastorNumScheme->unpackIndex(volumeID, zside, sector, zmodule);
1072  entry = aHit->getEntry();
1073  position = aHit->getPosition();
1074  if (verbosity)
1075  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n side , sector , module = " << zside << " , " << sector
1076  << " , " << zmodule << "\n nphotons = " << hitEnergy;
1077 
1078  if (verbosity)
1079  edm::LogVerbatim("CastorShowerLibraryMaker")
1080  << "\n packIndex = " << theCastorNumScheme->packIndex(zside, sector, zmodule);
1081 
1082  if (verbosity && time > 100.) {
1083  edm::LogVerbatim("CastorShowerLibraryMaker")
1084  << "\n nentries = " << nentries << "\n time[" << ihit << "] = " << time << "\n trackID[" << ihit
1085  << "] = " << aHit->getTrackID() << "\n volumeID[" << ihit << "] = " << volumeID << "\n nphotons[" << ihit
1086  << "] = " << hitEnergy << "\n side, sector, module = " << zside << ", " << sector << ", " << zmodule
1087  << "\n packIndex " << theCastorNumScheme->packIndex(zside, sector, zmodule) << "\n X,Y,Z = " << entry.x()
1088  << "," << entry.y() << "," << entry.z();
1089  }
1090  if (verbosity)
1091  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n Incident Energy = " << aHit->getIncidentEnergy() << " \n";
1092 
1093  // CaloG4Hit information
1094  shower->setDetID(volumeID);
1095  shower->setHitPosition(position);
1096  shower->setNphotons(hitEnergy);
1097  shower->setTime(time);
1098  nHits++;
1099  }
1100  // Write number of hits to CastorShowerEvent instance
1101  if (nHits == 0) {
1102  edm::LogVerbatim("CastorShowerLibraryMaker")
1103  << "No hits found for this track (trackID=" << ipart << ")." << std::endl;
1104  if (theCastorNumScheme)
1105  delete theCastorNumScheme;
1106  return false;
1107  }
1108  shower->setNhit(nHits);
1109 
1110  // update the event counters
1111  if (theCastorNumScheme)
1112  delete theCastorNumScheme;
1113  return true;
1114 }
1116  if (!SLShowerptr) {
1117  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nSLnEvtInBinE can be called only after BeginOfEvent\n\n";
1118  throw SimG4Exception("\n\nnullptr Pointer to the shower library.");
1119  }
1120  return SLShowerptr->nEvtInBinE.at(ebin);
1121 }
1122 
1124  if (!SLShowerptr) {
1125  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nSLnEvtInBinEta can be called only after BeginOfEvent\n\n";
1126  throw SimG4Exception("\n\nnullptr Pointer to the shower library.");
1127  }
1128  return SLShowerptr->nEvtInBinEta.at(ebin).at(etabin);
1129 }
1130 
1132  if (!SLShowerptr) {
1133  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nSLnEvtInBinPhi can be called only after BeginOfEvent\n\n";
1134  throw SimG4Exception("\n\nnullptr Pointer to the shower library.");
1135  }
1136  return SLShowerptr->nEvtInBinPhi.at(ebin).at(etabin).at(phibin);
1137 }
1139  if (!SLShowerptr) {
1140  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nSLisEBinFilled can be called only after BeginOfEvent\n\n";
1141  throw SimG4Exception("\n\nnullptr Pointer to the shower library.");
1142  }
1143  if (SLShowerptr->nEvtInBinE.at(ebin) < (int)SLShowerptr->nEvtPerBinE)
1144  return false;
1145  return true;
1146 }
1148  if (!SLShowerptr) {
1149  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nSLisEtaBinFilled can be called only after BeginOfEvent\n\n";
1150  throw SimG4Exception("\n\nnullptr Pointer to the shower library.");
1151  }
1152  if (SLShowerptr->nEvtInBinEta.at(ebin).at(etabin) < (int)SLShowerptr->nEvtPerBinEta)
1153  return false;
1154  return true;
1155 }
1157  if (!SLShowerptr) {
1158  edm::LogVerbatim("CastorShowerLibraryMaker") << "\n\nSLisPhiBinFilled can be called only after BeginOfEvent\n\n";
1159  throw SimG4Exception("\n\nnullptr Pointer to the shower library.");
1160  }
1161  if (SLShowerptr->nEvtInBinPhi.at(ebin).at(etabin).at(phibin) < (int)SLShowerptr->nEvtPerBinPhi)
1162  return false;
1163  return true;
1164 }
1166  const G4TrackVector* p_sec = aStep->GetSecondary();
1167  for (int i = 0; i < int(p_sec->size()); i++) {
1168  /*if (verbosity)*/ std::cout << "Killing track ID " << p_sec->at(i)->GetTrackID() << " and its secondaries"
1169  << " Produced by Process " << p_sec->at(i)->GetCreatorProcess()->GetProcessName()
1170  << " in the volume " << aStep->GetTrack()->GetVolume()->GetName() << std::endl;
1171  p_sec->at(i)->SetTrackStatus(fKillTrackAndSecondaries);
1172  }
1173 }
1174 
1175 void CastorShowerLibraryMaker::GetMissingEnergy(CaloG4HitCollection* theCAFI, double& miss_energy, double& tot_energy) {
1176  // Get the total deposited energy and the one from hit not associated to a primary
1177  miss_energy = 0;
1178  tot_energy = 0;
1179  int nhits = theCAFI->entries();
1180  for (int ihit = 0; ihit < nhits; ihit++) {
1181  int id = (*theCAFI)[ihit]->getTrackID();
1182  tot_energy += (*theCAFI)[ihit]->getEnergyDeposit();
1183  int hit_prim = 0;
1184  for (unsigned int i = 0; i < thePrims.size(); i++) {
1185  int particleType = thePrims.at(i)->GetPDGcode();
1186  if (MapOfSecondaries[particleType].find(id) != MapOfSecondaries[particleType].end())
1187  hit_prim = particleType;
1188  }
1189  if (hit_prim == 0) {
1190  std::cout << "Track ID " << id << " produced a hit which is not associated with a primary." << std::endl;
1191  miss_energy += (*theCAFI)[ihit]->getEnergyDeposit();
1192  }
1193  }
1194 }
1195 
1198 
void Clear(Option_t *option="") override
Log< level::Info, true > LogVerbatim
void setNBins(unsigned int n)
#define DEFINE_SIMWATCHER(type)
math::XYZPoint getPosition() const
Definition: CaloG4Hit.h:52
const double GeV
Definition: MathUtil.h:16
static std::vector< std::string > checklist log
void setTime(float t)
void setPrimEta(float eta)
void setPrimZ(float z)
void setDetID(unsigned int id)
int & SLnEvtInBinEta(int ebin, int etabin)
void setPrimPhi(float phi)
void setBin(double val)
std::vector< G4PrimaryParticle * > thePrims
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Theta< T > theta() const
bool FillShowerEvent(CaloG4HitCollection *, CastorShowerEvent *, int)
double getIncidentEnergy() const
Definition: CaloG4Hit.h:61
std::map< int, G4ThreeVector > PrimaryPosition
void KillSecondaries(const G4Step *step)
double npart
Definition: HydjetWrapper.h:46
int zside(DetId const &)
std::vector< std::vector< std::vector< std::vector< CastorShowerEvent > > > > SLBin3D
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:31
bool SLisEtaBinFilled(int ebin, int etabin)
static void unpackIndex(const uint32_t &idx, int &z, int &sector, int &zmodule)
void setNEvtPerBin(unsigned int n)
std::map< int, std::set< int > > MapOfSecondaries
std::vector< G4PrimaryParticle * > GetPrimary(const G4Event *)
CastorShowerLibraryInfo * hadInfo
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< std::vector< std::vector< int > > > nEvtInBinPhi
T min(T a, T b)
Definition: MathUtil.h:58
CastorShowerLibraryInfo * emInfo
CastorShowerLibraryMaker(const edm::ParameterSet &p)
void setPrimE(float e)
void setPrimY(float y)
void GetMissingEnergy(CaloG4HitCollection *, double &, double &)
void GetKinematics(G4PrimaryParticle *, double &px, double &py, double &pz, double &pInit, double &eta, double &phi)
int getTrackID() const
Definition: CaloG4Hit.h:64
void setPrimX(float x)
int & SLnEvtInBinPhi(int ebin, int etabin, int phibin)
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::vector< std::vector< int > > nEvtInBinEta
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
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
void setNEvts(unsigned int n)
G4THitsCollection< CaloG4Hit > CaloG4HitCollection
static int position[264][3]
Definition: ReadPGInfo.cc:289
bool SLisPhiBinFilled(int ebin, int etabin, int phibin)
std::map< int, G4ThreeVector > PrimaryMomentum
string end
Definition: dataset.py:937
double getTimeSlice() const
Definition: CaloG4Hit.h:67
list entry
Definition: mps_splice.py:68
tuple cout
Definition: gather_cfg.py:144
math::XYZPoint getEntry() const
Definition: CaloG4Hit.h:46
step
Definition: StallMonitor.cc:94
void update(const BeginOfJob *run) override
This routine will be called when the appropriate signal arrives.
uint32_t getUnitID() const
Definition: CaloG4Hit.h:66
static uint32_t packIndex(int z, int sector, int zmodule)
void setNphotons(float np)
void setNhit(unsigned int i)
void setHitPosition(const Point &p)
unsigned int getNhit()
double getEnergyDeposit() const
Definition: CaloG4Hit.h:79