CMS 3D CMS Logo

MaterialBudgetAction.cc
Go to the documentation of this file.
1 
4 
8 
14 
15 #include "G4Step.hh"
16 #include "G4Track.hh"
17 #include "G4UImanager.hh"
18 #include "G4UIterminal.hh"
19 #include "G4UItcsh.hh"
20 #include "G4LogicalVolumeStore.hh"
21 #include "G4TouchableHistory.hh"
22 #include "G4VPhysicalVolume.hh"
23 #include "G4VProcess.hh"
24 #include "G4ParticleTable.hh"
25 #include "G4ParticleDefinition.hh"
26 #include "G4ProcessManager.hh"
27 #include "G4TransportationManager.hh"
28 #include "DD4hep/Filter.h"
29 
30 #include <iostream>
31 
32 //-------------------------------------------------------------------------
34  theData = std::make_shared<MaterialBudgetData>();
35 
36  edm::ParameterSet m_Anal = iPSet.getParameter<edm::ParameterSet>("MaterialBudgetAction");
37 
38  //---- Accumulate material budget only inside selected volumes
39  std::string theHistoList = m_Anal.getParameter<std::string>("HistogramList");
40  std::vector<std::string> volList = m_Anal.getParameter<std::vector<std::string> >("SelectedVolumes");
41 
42  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: List of the selected volumes:";
43  for (const auto& it : volList) {
44  if (it != "None") {
45  theVolumeList.push_back(it);
46  edm::LogVerbatim("MaterialBudget") << it;
47  }
48  }
49 
50  // log
51  if (theHistoList == "Tracker") {
52  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: running in Tracker Mode";
53  } else if (theHistoList == "ECAL") {
54  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: running in Ecal Mode";
55  } else if (theHistoList == "Mtd") {
56  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: running in Mtd Mode";
57  } else if (theHistoList == "HGCal") {
58  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: running in HGCal Mode";
59  } else {
60  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: running in General Mode";
61  }
62 
63  //---- Stop track when a process occurs
64  theProcessToStop = m_Anal.getParameter<std::string>("StopAfterProcess");
65  LogDebug("MaterialBudget") << "MaterialBudgetAction: stop at process " << theProcessToStop;
66 
67  //---- Save histos to ROOT file
68  std::string saveToHistosFile = m_Anal.getParameter<std::string>("HistosFile");
69  if (saveToHistosFile != "None") {
70  saveToHistos = true;
71  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: saving histograms to " << saveToHistosFile;
72  theHistoMgr = std::make_shared<TestHistoMgr>();
73  if (theHistoList == "Tracker") {
74  theHistos = std::make_shared<MaterialBudgetTrackerHistos>(theData, theHistoMgr, saveToHistosFile);
75  } else if (theHistoList == "ECAL") {
76  theHistos = std::make_shared<MaterialBudgetEcalHistos>(theData, theHistoMgr, saveToHistosFile);
77  } else if (theHistoList == "Mtd") {
78  theHistos = std::make_shared<MaterialBudgetMtdHistos>(theData, theHistoMgr, saveToHistosFile);
79  theData->setMtdmode(true);
80  } else if (theHistoList == "HGCal") {
81  theHistos = std::make_shared<MaterialBudgetHGCalHistos>(theData,
83  saveToHistosFile,
84  m_Anal.getParameter<double>("minZ"),
85  m_Anal.getParameter<double>("maxZ"),
86  m_Anal.getParameter<int>("nintZ"),
87  m_Anal.getParameter<double>("rMin"),
88  m_Anal.getParameter<double>("rMax"),
89  m_Anal.getParameter<int>("nrbin"),
90  m_Anal.getParameter<double>("etaMin"),
91  m_Anal.getParameter<double>("etaMax"),
92  m_Anal.getParameter<int>("netabin"),
93  m_Anal.getParameter<double>("phiMin"),
94  m_Anal.getParameter<double>("phiMax"),
95  m_Anal.getParameter<int>("nphibin"),
96  m_Anal.getParameter<double>("RMin"),
97  m_Anal.getParameter<double>("RMax"),
98  m_Anal.getParameter<int>("nRbin"));
99  //In HGCal mode, so tell data class
100  theData->setHGCalmode(true);
101  } else {
102  theHistos = std::make_shared<MaterialBudgetHistos>(theData, theHistoMgr, saveToHistosFile);
103  }
104  } else {
105  edm::LogWarning("MaterialBudget") << "MaterialBudgetAction: No histograms file specified";
106  saveToHistos = false;
107  }
108 
109  //---- Save material budget info to TEXT file
110  std::string saveToTxtFile = m_Anal.getParameter<std::string>("TextFile");
111  if (saveToTxtFile != "None") {
112  saveToTxt = true;
113  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: saving text info to " << saveToTxtFile;
114  theTxt = std::make_shared<MaterialBudgetTxt>(theData, saveToTxtFile);
115  } else {
116  saveToTxt = false;
117  }
118 
119  //---- Compute all the steps even if not stored on file
120  bool allSteps = m_Anal.getParameter<bool>("AllStepsToTree");
121  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: all steps are computed " << allSteps;
122  if (allSteps)
123  theData->SetAllStepsToTree();
124 
125  //---- Save tree to ROOT file
126  std::string saveToTreeFile = m_Anal.getParameter<std::string>("TreeFile");
127  if (saveToTreeFile != "None") {
128  saveToTree = true;
129  theTree = std::make_shared<MaterialBudgetTree>(theData, saveToTreeFile);
130  } else {
131  saveToTree = false;
132  }
133  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: saving ROOT TTree to " << saveToTreeFile;
134 
135  //---- Track the first decay products of the main particle
136  // if their kinetic energy is greater than Ekin
137  storeDecay = m_Anal.getUntrackedParameter<bool>("storeDecay", false);
138  Ekin = m_Anal.getUntrackedParameter<double>("EminDecayProd", 1000.0); // MeV
139  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction: decay products steps are stored (" << storeDecay
140  << ") if their kinetic energy is greater than " << Ekin << " MeV";
141  firstParticle = false;
142 }
143 
144 //-------------------------------------------------------------------------
146 
147 //-------------------------------------------------------------------------
149  //----- Check that selected volumes are indeed part of the geometry
150  const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
151 
152  for (const auto& volcite : theVolumeList) {
153  bool volFound = false;
154  for (const auto& lvcite : *lvs) {
155  if (static_cast<std::string>(dd4hep::dd::noNamespace(lvcite->GetName())) == static_cast<std::string>(volcite)) {
156  volFound = true;
157  break;
158  }
159  }
160  if (!volFound) {
161  edm::LogWarning("MaterialBudget") << "MaterialBudgetAction: selected volume not found in geometry " << volcite;
162  }
163  }
164 
165  //----- Check process selected is one of the available ones
166  bool procFound = false;
167  if (theProcessToStop == "None") {
168  procFound = true;
169  } else {
170  G4ParticleTable* partTable = G4ParticleTable::GetParticleTable();
171  int siz = partTable->size();
172  for (int ii = 0; ii < siz; ii++) {
173  G4ParticleDefinition* particle = partTable->GetParticle(ii);
174 
175  //--- All processes of this particle
176  G4ProcessManager* pmanager = particle->GetProcessManager();
177  G4ProcessVector* pvect = pmanager->GetProcessList();
178  int sizproc = pvect->size();
179  for (int jj = 0; jj < sizproc; jj++) {
180  if ((*pvect)[jj]->GetProcessName() == theProcessToStop) {
181  procFound = true;
182  break;
183  }
184  }
185  }
186  }
187 
188  if (!procFound) {
189  edm::LogWarning("MaterialBudget") << "MaterialBudgetAction: selected process to stop tracking not found "
190  << theProcessToStop;
191  }
192 }
193 
194 //-------------------------------------------------------------------------
196  const G4Track* aTrack = (*trk)(); // recover G4 pointer if wanted
197 
198  // that was a temporary action while we're sorting out
199  // about # of secondaries (produced if CutsPerRegion=true)
200 
201  LogDebug("MaterialBudget") << "MaterialBudgetAction: Track ID " << aTrack->GetTrackID() << "Track parent ID "
202  << aTrack->GetParentID() << "PDG Id. = " << aTrack->GetDefinition()->GetPDGEncoding()
203  << "Ekin = " << aTrack->GetKineticEnergy() << " MeV";
204 
205  if (aTrack->GetCreatorProcess())
206  LogDebug("MaterialBudget") << "MaterialBudgetAction: produced through "
207  << aTrack->GetCreatorProcess()->GetProcessType();
208 
209  if (aTrack->GetTrackID() == 1) {
210  firstParticle = true;
211  } else {
212  firstParticle = false;
213  }
214 
215  if (storeDecay) { // if record of the decay is requested
216  if (aTrack->GetCreatorProcess()) {
217  if (aTrack->GetParentID() == 1 &&
218  // aTrack->GetCreatorProcess()->GetProcessType() == 6
219  // &&
220  aTrack->GetKineticEnergy() > Ekin) {
221  // continue
222  } else {
223  G4Track* aTracknc = const_cast<G4Track*>(aTrack);
224  aTracknc->SetTrackStatus(fStopAndKill);
225  return;
226  }
227  } // particles produced from a decay (type=6) of the main particle (ID=1) with Kinetic Energy [MeV] > Ekin
228  } else { // kill all the other particles (take only the main one until it disappears) if decay not stored
229  if (aTrack->GetParentID() != 0) {
230  G4Track* aTracknc = const_cast<G4Track*>(aTrack);
231  aTracknc->SetTrackStatus(fStopAndKill);
232  return;
233  }
234  }
235 
236  theData->dataStartTrack(aTrack);
237 
238  if (saveToTree)
239  theTree->fillStartTrack();
240  if (saveToHistos)
241  theHistos->fillStartTrack();
242  if (saveToTxt)
243  theTxt->fillStartTrack();
244 }
245 
246 //-------------------------------------------------------------------------
247 void MaterialBudgetAction::update(const G4Step* aStep) {
248  //----- Check it is inside one of the volumes selected
249  if (!theVolumeList.empty()) {
250  if (!CheckTouchableInSelectedVolumes(aStep->GetTrack()->GetTouchable()))
251  return;
252  }
253 
254  //---------- each step
255  theData->dataPerStep(aStep);
256  if (saveToTree)
257  theTree->fillPerStep();
258  if (saveToHistos)
259  theHistos->fillPerStep();
260  if (saveToTxt)
261  theTxt->fillPerStep();
262 
263  //----- Stop tracking after selected process
264  if (StopAfterProcess(aStep)) {
265  G4Track* track = aStep->GetTrack();
266  track->SetTrackStatus(fStopAndKill);
267  }
268 
269  return;
270 }
271 
272 //-------------------------------------------------------------------------
274  const G4TouchableHistory* theTouchable = (const G4TouchableHistory*)(aStepPoint->GetTouchable());
275  G4int num_levels = theTouchable->GetHistoryDepth();
276 
277  if (theTouchable->GetVolume()) {
278  return static_cast<std::string>(dd4hep::dd::noNamespace(theTouchable->GetVolume(num_levels - 1)->GetName()));
279  } else {
280  return "OutOfWorld";
281  }
282 }
283 
284 //-------------------------------------------------------------------------
286  const G4TouchableHistory* theTouchable = (const G4TouchableHistory*)(aStepPoint->GetTouchable());
287  G4int num_levels = theTouchable->GetHistoryDepth();
288 
289  if (theTouchable->GetVolume()) {
290  return static_cast<std::string>(dd4hep::dd::noNamespace(theTouchable->GetVolume(num_levels - 3)->GetName()));
291  } else {
292  return "OutOfWorld";
293  }
294 }
295 
296 //-------------------------------------------------------------------------
298  const G4Track* aTrack = (*trk)(); // recover G4 pointer if wanted
299  theData->dataEndTrack(aTrack);
300 
301  if (saveToTree)
302  theTree->fillEndTrack();
303  if (saveToHistos)
304  theHistos->fillEndTrack();
305  if (saveToTxt)
306  theTxt->fillEndTrack();
307 }
308 
309 //-------------------------------------------------------------------------
311  // endOfRun calls TestHistoMgr::save() allowing to write
312  // the ROOT files containing the histograms
313 
314  if (saveToHistos)
315  theHistos->endOfRun();
316  if (saveToTxt)
317  theHistos->endOfRun();
318  if (saveToTree)
319  theTree->endOfRun();
320 
321  return;
322 }
323 
324 //-------------------------------------------------------------------------
326  size_t volh = touch->GetHistoryDepth();
327  for (int ii = volh; ii >= 0; ii--) {
328  G4String name = static_cast<std::string>(dd4hep::dd::noNamespace(touch->GetVolume(ii)->GetName()));
329  if (std::find(theVolumeList.begin(), theVolumeList.end(), name) != theVolumeList.end())
330  return true;
331  }
332  return false;
333 }
334 
335 //-------------------------------------------------------------------------
336 bool MaterialBudgetAction::StopAfterProcess(const G4Step* aStep) {
337  if (theProcessToStop.empty())
338  return false;
339 
340  if (aStep->GetPostStepPoint()->GetProcessDefinedStep() == nullptr)
341  return false;
342  if (aStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName() == theProcessToStop) {
343  edm::LogVerbatim("MaterialBudget") << "MaterialBudgetAction :"
344  << aStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName();
345  return true;
346  } else {
347  return false;
348  }
349 }
bool CheckTouchableInSelectedVolumes(const G4VTouchable *touch)
Log< level::Info, true > LogVerbatim
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
std::shared_ptr< MaterialBudgetFormat > theHistos
MaterialBudgetAction(const edm::ParameterSet &)
std::shared_ptr< TestHistoMgr > theHistoMgr
std::shared_ptr< MaterialBudgetTxt > theTxt
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
std::shared_ptr< MaterialBudgetTree > theTree
ii
Definition: cuy.py:589
bool StopAfterProcess(const G4Step *aStep)
std::string getPartName(G4StepPoint *aStepPoint)
std::vector< G4String > theVolumeList
Log< level::Warning, false > LogWarning
std::string getSubDetectorName(G4StepPoint *aStepPoint)
std::shared_ptr< MaterialBudgetData > theData
void update(const BeginOfRun *) override
This routine will be called when the appropriate signal arrives.
#define LogDebug(id)