CMS 3D CMS Logo

PrintMaterialBudgetInfo.cc
Go to the documentation of this file.
5 
15 
16 #include "G4Run.hh"
17 #include "G4PhysicalVolumeStore.hh"
18 #include "G4LogicalVolumeStore.hh"
19 #include "G4VPhysicalVolume.hh"
20 #include "G4LogicalVolume.hh"
21 #include "G4VSolid.hh"
22 #include "G4Material.hh"
23 #include "G4NavigationHistory.hh"
24 #include "G4Track.hh"
25 #include "G4VisAttributes.hh"
26 #include "G4UserLimits.hh"
27 #include "G4TransportationManager.hh"
28 #include "G4UnitsTable.hh"
29 #include "Randomize.hh"
30 
31 #include <iostream>
32 #include <fstream>
33 #include <memory>
34 #include <set>
35 #include <vector>
36 #include <string>
37 
38 typedef std::map<G4VPhysicalVolume*, G4VPhysicalVolume*, std::less<G4VPhysicalVolume*> > mpvpv;
39 typedef std::multimap<G4LogicalVolume*, G4VPhysicalVolume*, std::less<G4LogicalVolume*> > mmlvpv;
40 
42  public Observer<const BeginOfJob*>,
43  public Observer<const BeginOfRun*> {
44 public:
46  ~PrintMaterialBudgetInfo() override;
47 
48 private:
49  void update(const BeginOfJob* job) override{};
50  void update(const BeginOfRun* run) override;
51  void dumpHeader(std::ostream& out = G4cout);
52  void dumpLaTeXHeader(std::ostream& out = G4cout);
53  void dumpHierarchyLeaf(G4VPhysicalVolume* pv,
54  G4LogicalVolume* lv,
55  unsigned int leafDepth,
56  std::ostream& weightOut = G4cout,
57  std::ostream& texOut = G4cout);
58  void printInfo(G4VPhysicalVolume* pv,
59  G4LogicalVolume* lv,
60  unsigned int leafDepth,
61  std::ostream& weightOut = G4cout,
62  std::ostream& texOut = G4cout);
63  void dumpElementMassFraction(std::ostream& elementOut = G4cout);
64  void dumpLaTeXFooter(std::ostream& out = G4cout);
65 
66 private:
68  int nchar;
70  G4NavigationHistory fHistory;
72  unsigned int levelFound;
73  std::ofstream weightOutputFile;
74  std::ofstream elementOutputFile;
75  std::ofstream texOutputFile;
76  std::vector<std::string> elementNames;
77  std::vector<double> elementTotalWeight;
78  std::vector<double> elementWeightFraction;
79 
82 };
83 
85  name = p.getUntrackedParameter<std::string>("Name", "*");
86  nchar = name.find('*');
87  name.assign(name, 0, nchar);
88  G4cout << "PrintMaterialBudget selected volume " << name << G4endl;
89  volumeFound = false;
90  std::string weightFileName = name + ".weight";
91  weightOutputFile.open(weightFileName.c_str());
92  std::string elementFileName = name + ".element";
93  elementOutputFile.open(elementFileName.c_str());
94  std::string texFileName = name + "_table.tex";
95  texOutputFile.open(texFileName.c_str());
96  G4cout << "PrintMaterialBudget output file " << weightFileName << G4endl;
97  G4cout << "PrintMaterialBudget output file " << elementFileName << G4endl;
98  G4cout << "PrintMaterialBudget output file " << texFileName << G4endl;
99  elementNames.clear();
100  elementTotalWeight.clear();
101  elementWeightFraction.clear();
102 }
103 
105 
107  G4Random::setTheEngine(new CLHEP::RanecuEngine);
108  // Physical Volume
109  G4VPhysicalVolume* theTopPV =
110  G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
111  assert(theTopPV);
112  // Logical Volume
113  G4LogicalVolume* lv = theTopPV->GetLogicalVolume();
114  unsigned int leafDepth = 0;
115  // the first time fill the vectors of elements
116  if (elementNames.empty() && elementTotalWeight.empty() && elementWeightFraction.empty()) {
117  for (unsigned int iElement = 0; iElement < G4Element::GetNumberOfElements();
118  iElement++) { // first element in table is 0
119  elementNames.push_back("rr");
120  elementTotalWeight.push_back(0);
121  elementWeightFraction.push_back(0);
122  }
123  }
126  dumpHierarchyLeaf(theTopPV, lv, leafDepth, weightOutputFile, texOutputFile);
129  //
130 }
131 
133  out << "Geom."
134  << "\t"
135  << "Volume"
136  << "\t"
137  << "\t"
138  << "Copy"
139  << "\t"
140  << "Solid"
141  << "\t"
142  << "\t"
143  << "Material"
144  << "\t"
145  << "Density"
146  << "\t"
147  << "\t"
148  << "Mass"
149  << "\t"
150  << "\t" << G4endl;
151  out << "Level"
152  << "\t"
153  << "Name"
154  << "\t"
155  << "\t"
156  << "Number"
157  << "\t"
158  << "Name"
159  << "\t"
160  << "\t"
161  << "Name"
162  << "\t"
163  << "\t"
164  << "[g/cm3]"
165  << "\t"
166  << "\t"
167  << "[g] "
168  << "\t"
169  << "\t" << G4endl;
170 }
171 
173  out << "\\begin{table}[h!]" << G4endl << " \\caption{\\textsf {" << name << "} volume list.}" << G4endl
174  << " \\label{tab: " << name << "}" << G4endl << " \\begin{center}" << G4endl << " \\begin{tabular}{ccccccc}"
175  << G4endl << " \\hline" << G4endl;
176  out << " Geom."
177  << "\t & "
178  << " Volume"
179  << "\t & "
180  << " Copy"
181  << "\t & "
182  << " Solid"
183  << "\t & "
184  << " Material"
185  << "\t & "
186  << " Density"
187  << "\t & "
188  << " Mass"
189  << "\t \\\\ " << G4endl;
190  out << " Level"
191  << "\t & "
192  << " Name"
193  << "\t & "
194  << " Number"
195  << "\t & "
196  << " Name"
197  << "\t & "
198  << " Name"
199  << "\t & "
200  << " "
201  << "\t & "
202  << " "
203  << "\t \\\\ " << G4endl << " \\hline\\hline" << G4endl;
204 }
205 
207  out << " \\hline" << G4endl << " \\end{tabular}" << G4endl << " \\end{center}" << G4endl << "\\end{table}"
208  << G4endl;
209 }
210 
212  G4VPhysicalVolume* pv, G4LogicalVolume* lv, unsigned int leafDepth, std::ostream& weightOut, std::ostream& texOut) {
213  if (volumeFound && (leafDepth <= levelFound))
214  return;
215  if (volumeFound && (leafDepth > levelFound))
216  printInfo(pv, lv, leafDepth, weightOut, texOut);
217 
218  // choose mother volume
219  std::string lvname = lv->GetName();
220  lvname.assign(lvname, 0, nchar);
221  if (lvname == name) {
222  volumeFound = true;
223  levelFound = leafDepth;
224  printInfo(pv, lv, leafDepth, weightOut, texOut);
225  texOut << " \\hline" << G4endl;
226  }
227 
228  //----- Get LV daughters from list of PV daughters
229  mmlvpv lvpvDaughters;
230  std::set<G4LogicalVolume*> lvDaughters;
231  int NoDaughters = lv->GetNoDaughters();
232  while ((NoDaughters--) > 0) {
233  G4VPhysicalVolume* pvD = lv->GetDaughter(NoDaughters);
234  lvpvDaughters.insert(mmlvpv::value_type(pvD->GetLogicalVolume(), pvD));
235  lvDaughters.insert(pvD->GetLogicalVolume());
236  }
237 
238  std::set<G4LogicalVolume*>::const_iterator scite;
239  mmlvpv::const_iterator mmcite;
240 
241  //----- Dump daughters PV and LV
242  for (scite = lvDaughters.begin(); scite != lvDaughters.end(); scite++) {
243  std::pair<mmlvpv::iterator, mmlvpv::iterator> mmER = lvpvDaughters.equal_range(*scite);
244  //----- Dump daughters PV of this LV
245  for (mmcite = mmER.first; mmcite != mmER.second; mmcite++)
246  dumpHierarchyLeaf((*mmcite).second, *scite, leafDepth + 1, weightOut, texOut);
247  }
248 }
249 
251  G4VPhysicalVolume* pv, G4LogicalVolume* lv, unsigned int leafDepth, std::ostream& weightOut, std::ostream& texOut) {
252  double density = lv->GetMaterial()->GetDensity();
253  double weight = lv->GetMass(false, false);
254 
255  std::string volumeName = lv->GetName();
256  if (volumeName.size() < 8)
257  volumeName.append("\t");
258 
259  std::string solidName = lv->GetSolid()->GetName();
260  if (solidName.size() < 8)
261  solidName.append("\t");
262 
263  std::string materialName = lv->GetMaterial()->GetName();
264  if (materialName.size() < 8)
265  materialName.append("\t");
266 
267  //----- dump info
268  weightOut << leafDepth << "\t" << volumeName << "\t" << pv->GetCopyNo() << "\t" << solidName << "\t" << materialName
269  << "\t" << G4BestUnit(density, "Volumic Mass") << "\t" << G4BestUnit(weight, "Mass") << "\t" << G4endl;
270  //
271  texOut << "\t" << leafDepth << "\t & " << stringLaTeXUnderscore(volumeName) << "\t & " << pv->GetCopyNo() << "\t & "
272  << stringLaTeXUnderscore(solidName) << "\t & " << stringLaTeXUnderscore(materialName) << "\t & "
273  << stringLaTeXSuperscript(G4BestUnit(density, "Volumic Mass")) << "\t & "
274  << stringLaTeXSuperscript(G4BestUnit(weight, "Mass")) << "\t \\\\ " << G4endl;
275  //
276  for (unsigned int iElement = 0; iElement < (unsigned int)lv->GetMaterial()->GetNumberOfElements(); iElement++) {
277  // exclude Air in element weight fraction computation
278  if (materialName.find("Air")) {
279  std::string elementName = lv->GetMaterial()->GetElement(iElement)->GetName();
280  double elementMassFraction = lv->GetMaterial()->GetFractionVector()[iElement];
281  double elementWeight = weight * elementMassFraction;
282  unsigned int elementIndex = (unsigned int)lv->GetMaterial()->GetElement(iElement)->GetIndex();
283  elementNames[elementIndex] = elementName;
284  elementTotalWeight[elementIndex] += elementWeight;
285  }
286  }
287 }
288 
289 void PrintMaterialBudgetInfo::dumpElementMassFraction(std::ostream& elementOut) {
290  // calculate mass fraction
291  double totalWeight = 0.0;
292  double totalFraction = 0.0;
293  for (unsigned int iElement = 0; iElement < (unsigned int)elementTotalWeight.size(); iElement++) {
294  totalWeight += elementTotalWeight[iElement];
295  }
296  // calculate element mass fractions
297  for (unsigned int iElement = 0; iElement < (unsigned int)elementTotalWeight.size(); iElement++) {
298  elementWeightFraction[iElement] = elementTotalWeight[iElement] / totalWeight;
299  totalFraction += elementWeightFraction[iElement];
300  }
301  // header
302  elementOut << "Element"
303  << "\t\t"
304  << "Index"
305  << "\t"
306  << "Total Mass"
307  << "\t"
308  << "Mass Fraction "
309  << "\t" << G4endl;
310  // dump
311  for (unsigned int iElement = 0; iElement < (unsigned int)elementTotalWeight.size(); iElement++) {
312  if (elementNames[iElement] != "rr") {
313  if (elementNames[iElement].size() < 8)
314  elementNames[iElement].append("\t");
315  elementOut << elementNames[iElement] << "\t" << iElement << "\t"
316  << G4BestUnit(elementTotalWeight[iElement], "Mass") << "\t" << elementWeightFraction[iElement]
317  << G4endl;
318  }
319  }
320  elementOut << "\n\t\tTotal Weight without Air " << G4BestUnit(totalWeight, "Mass") << "\tTotal Fraction "
321  << totalFraction << G4endl;
322 }
323 
325  // To replace '\' with '\_' to compile LaTeX output
326  std::string stringoutput;
327 
328  for (unsigned int i = 0; i < stringname.length(); i++) {
329  if (stringname.substr(i, 1) == "_") {
330  stringoutput += "\\_";
331  } else {
332  stringoutput += stringname.substr(i, 1);
333  }
334  }
335 
336  return stringoutput;
337 }
338 
340  // To replace 'm3' with 'm$^3$' to compile LaTeX output
341  std::string stringoutput = stringname.substr(0, 1);
342 
343  for (unsigned int i = 1; i < stringname.length(); i++) {
344  if (stringname.substr(i - 1, 1) == "m" && stringname.substr(i, 1) == "3") {
345  stringoutput += "$^3$";
346  } else {
347  stringoutput += stringname.substr(i, 1);
348  }
349  }
350 
351  return stringoutput;
352 }
353 
356 
size
Write out results.
std::multimap< G4LogicalVolume *, G4VPhysicalVolume *, std::less< G4LogicalVolume * > > mmlvpv
#define DEFINE_SIMWATCHER(type)
void dumpLaTeXFooter(std::ostream &out=G4cout)
std::vector< std::string > elementNames
Definition: weight.py:1
assert(be >=bs)
void dumpLaTeXHeader(std::ostream &out=G4cout)
std::vector< double > elementWeightFraction
std::vector< double > elementTotalWeight
void dumpElementMassFraction(std::ostream &elementOut=G4cout)
void dumpHierarchyLeaf(G4VPhysicalVolume *pv, G4LogicalVolume *lv, unsigned int leafDepth, std::ostream &weightOut=G4cout, std::ostream &texOut=G4cout)
PrintMaterialBudgetInfo(edm::ParameterSet const &p)
std::multimap< G4LogicalVolume *, G4VPhysicalVolume *, std::less< G4LogicalVolume * > > mmlvpv
std::string stringLaTeXSuperscript(std::string stringname)
std::string stringLaTeXUnderscore(std::string stringname)
void update(const BeginOfJob *job) override
This routine will be called when the appropriate signal arrives.
void printInfo(G4VPhysicalVolume *pv, G4LogicalVolume *lv, unsigned int leafDepth, std::ostream &weightOut=G4cout, std::ostream &texOut=G4cout)
std::map< G4VPhysicalVolume *, G4VPhysicalVolume *, std::less< G4VPhysicalVolume * > > mpvpv
void dumpHeader(std::ostream &out=G4cout)