CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/SimG4Core/PrintGeomInfo/src/PrintMaterialBudgetInfo.cc

Go to the documentation of this file.
00001 #include "SimG4Core/PrintGeomInfo/interface/PrintMaterialBudgetInfo.h"
00002 
00003 #include "SimG4Core/Notification/interface/BeginOfJob.h"
00004 #include "SimG4Core/Notification/interface/BeginOfRun.h"
00005 #include "SimG4Core/Notification/interface/SimG4Exception.h"
00006 
00007 #include "FWCore/Framework/interface/EventSetup.h"
00008 #include "FWCore/Framework/interface/ESHandle.h"
00009 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00010 #include "DetectorDescription/Core/interface/DDCompactView.h"
00011 #include "DetectorDescription/Core/interface/DDFilter.h"
00012 #include "DetectorDescription/Core/interface/DDFilteredView.h"
00013 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00014 #include "DetectorDescription/Core/interface/DDSplit.h"
00015 #include "DetectorDescription/Core/interface/DDValue.h"
00016 
00017 #include "G4Run.hh"
00018 #include "G4PhysicalVolumeStore.hh"
00019 #include "G4LogicalVolumeStore.hh"
00020 #include "G4VPhysicalVolume.hh"
00021 #include "G4LogicalVolume.hh"
00022 #include "G4VSolid.hh"
00023 #include "G4Material.hh"
00024 #include "G4Track.hh"
00025 #include "G4VisAttributes.hh"
00026 #include "G4UserLimits.hh"
00027 #include "G4TransportationManager.hh"
00028 #include "G4UnitsTable.hh"
00029 
00030 #include <set>
00031 
00032 PrintMaterialBudgetInfo::PrintMaterialBudgetInfo(const edm::ParameterSet& p) {
00033   name  = p.getUntrackedParameter<std::string>("Name","*");
00034   nchar = name.find("*");
00035   name.assign(name,0,nchar);
00036   std::cout << "PrintMaterialBudget selected volume " << name << std::endl;
00037   volumeFound = false;
00038   std::string weightFileName = name+".weight";
00039   weightOutputFile.open( weightFileName.c_str() );
00040   std::string elementFileName = name+".element";
00041   elementOutputFile.open( elementFileName.c_str() );
00042   std::string texFileName = name+"_table.tex";
00043   texOutputFile.open( texFileName.c_str() );
00044   std::cout << "PrintMaterialBudget output file " << weightFileName  << std::endl;
00045   std::cout << "PrintMaterialBudget output file " << elementFileName << std::endl;
00046   std::cout << "PrintMaterialBudget output file " << texFileName     << std::endl;
00047   elementNames.clear();
00048   elementTotalWeight.clear();
00049   elementWeightFraction.clear();
00050 }
00051 
00052 PrintMaterialBudgetInfo::~PrintMaterialBudgetInfo() {}
00053 
00054 void PrintMaterialBudgetInfo::update(const BeginOfRun* run) {
00055   
00056   // Physical Volume
00057   theTopPV = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()->GetWorldVolume();
00058   // Logical Volume
00059   G4LogicalVolume*  lv = theTopPV->GetLogicalVolume();
00060   unsigned int leafDepth = 0;
00061   // the first time fill the vectors of elements
00062   if( elementNames.size()==0 && elementTotalWeight.size()==0 && elementWeightFraction.size()==0) {
00063     for(unsigned int iElement = 0;
00064         iElement < lv->GetMaterial()->GetElement(iElement)->GetElementTable()->size();
00065         iElement++) { // first element in table is 0
00066       elementNames.push_back("rr");
00067       elementTotalWeight.push_back(0);
00068       elementWeightFraction.push_back(0);
00069     }
00070   }
00071   dumpHeader(weightOutputFile);
00072   dumpLaTeXHeader(texOutputFile);
00073   dumpHierarchyLeaf(theTopPV, lv, leafDepth, weightOutputFile, texOutputFile);
00074   dumpElementMassFraction(elementOutputFile);
00075   dumpLaTeXFooter(texOutputFile);
00076   //
00077 }
00078 
00079 void PrintMaterialBudgetInfo::dumpHeader(std::ostream& out ) {
00080   out << "Geom."      << "\t"
00081       << "Volume"     << "\t" << "\t"
00082       << "Copy"       << "\t"
00083       << "Solid"      << "\t" << "\t"
00084       << "Material"   << "\t"
00085       << "Density"    << "\t" << "\t"
00086       << "Mass"       << "\t" << "\t"
00087       << std::endl;
00088   out << "Level"     << "\t"
00089       << "Name"      << "\t" << "\t"
00090       << "Number"    << "\t"
00091       << "Name"      << "\t" << "\t"
00092       << "Name"      << "\t" << "\t"
00093       << "[g/cm3]"   << "\t" << "\t"
00094       << "[g]    "   << "\t" << "\t"
00095       << std::endl;
00096 }
00097 
00098 void PrintMaterialBudgetInfo::dumpLaTeXHeader(std::ostream& out ) {
00099   out << "\\begin{table}[h!]"                                     << std::endl
00100       << "  \\caption{\\textsf {" << name << "} volume list.}"               << std::endl
00101       << "  \\label{tab: " << name << "}"                         << std::endl
00102       << "  \\begin{center}"                                      << std::endl
00103       << "    \\begin{tabular}{ccccccc}"                          << std::endl
00104       << "      \\hline"                                          << std::endl;
00105   out << "      Geom."      << "\t & "
00106       << "      Volume"     << "\t & "
00107       << "      Copy"       << "\t & "
00108       << "      Solid"      << "\t & "
00109       << "      Material"   << "\t & "
00110       << "      Density"    << "\t & "
00111       << "      Mass"       << "\t \\\\ "
00112       << std::endl;
00113   out << "      Level"      << "\t & "
00114       << "      Name"       << "\t & "
00115       << "      Number"     << "\t & "
00116       << "      Name"       << "\t & "
00117       << "      Name"       << "\t & "
00118       << "                " << "\t & "
00119       << "                " << "\t \\\\ "
00120       << std::endl
00121       << "      \\hline\\hline"
00122       << std::endl;
00123 }
00124 
00125 void PrintMaterialBudgetInfo::dumpLaTeXFooter(std::ostream& out ) {
00126   out << "      \\hline"      << std::endl
00127       << "    \\end{tabular}" << std::endl
00128       << "  \\end{center}"    << std::endl
00129       << "\\end{table}"       << std::endl;
00130 }
00131 
00132 void PrintMaterialBudgetInfo::dumpHierarchyLeaf(G4VPhysicalVolume* pv, G4LogicalVolume* lv,
00133                                                 unsigned int leafDepth,
00134                                                 std::ostream& weightOut,
00135                                                 std::ostream& texOut ) {
00136   
00137   if( volumeFound && ( leafDepth <= levelFound ) ) return; 
00138   if( volumeFound && ( leafDepth >  levelFound ) ) printInfo(pv, lv, leafDepth, weightOut, texOut);
00139   
00140   // choose mother volume
00141   std::string lvname = lv->GetName();
00142   lvname.assign(lvname,0,nchar);
00143   if (lvname == name) {
00144     volumeFound = true;
00145     levelFound  = leafDepth;
00146     printInfo(pv, lv, leafDepth, weightOut, texOut);
00147     texOut << "      \\hline" << std::endl;
00148   }
00149   
00150   //----- Get LV daughters from list of PV daughters
00151   mmlvpv lvpvDaughters;
00152   std::set< G4LogicalVolume* > lvDaughters;
00153   int NoDaughters = lv->GetNoDaughters();
00154   while ((NoDaughters--)>0)
00155     {
00156       G4VPhysicalVolume* pvD = lv->GetDaughter(NoDaughters);
00157       lvpvDaughters.insert(mmlvpv::value_type(pvD->GetLogicalVolume(), pvD));
00158       lvDaughters.insert(pvD->GetLogicalVolume());
00159     }
00160   
00161   std::set< G4LogicalVolume* >::const_iterator scite;
00162   mmlvpv::const_iterator mmcite;
00163   
00164   //----- Dump daughters PV and LV
00165   for (scite = lvDaughters.begin(); scite != lvDaughters.end(); scite++) {
00166     std::pair< mmlvpv::iterator, mmlvpv::iterator > mmER = lvpvDaughters.equal_range(*scite);    
00167     //----- Dump daughters PV of this LV
00168     for (mmcite = mmER.first ; mmcite != mmER.second; mmcite++) 
00169       dumpHierarchyLeaf((*mmcite).second, *scite, leafDepth+1, weightOut, texOut );
00170   }
00171   
00172 }
00173 
00174 void PrintMaterialBudgetInfo::printInfo(G4VPhysicalVolume* pv, G4LogicalVolume* lv, unsigned int leafDepth,
00175                                         std::ostream& weightOut, std::ostream& texOut ) {
00176   
00177   double density = lv->GetMaterial()->GetDensity();
00178   double weight  = lv->GetMass(false,false);
00179   
00180   std::string volumeName = lv->GetName();
00181   if(volumeName.size()<8) volumeName.append("\t");
00182   
00183   std::string solidName = lv->GetSolid()->GetName();
00184   if(solidName.size()<8) solidName.append("\t");
00185     
00186   std::string materialName = lv->GetMaterial()->GetName();
00187   if(materialName.size()<8) materialName.append("\t");
00188   
00189   //----- dump info 
00190   weightOut << leafDepth                                            << "\t"
00191             << volumeName                                           << "\t"
00192             << pv->GetCopyNo()                                      << "\t"
00193             << solidName                                            << "\t"
00194             << materialName                                         << "\t"
00195             << G4BestUnit(density,"Volumic Mass")                   << "\t"
00196             << G4BestUnit(weight,"Mass")                            << "\t"
00197             << std::endl;
00198   //
00199   texOut << "\t" 
00200          << leafDepth                                                  << "\t & "
00201          << stringLaTeXUnderscore(volumeName)                          << "\t & "
00202          << pv->GetCopyNo()                                            << "\t & "
00203          << stringLaTeXUnderscore(solidName)                           << "\t & "
00204          << stringLaTeXUnderscore(materialName)                        << "\t & "
00205          << stringLaTeXSuperscript(G4BestUnit(density,"Volumic Mass")) << "\t & "
00206          << stringLaTeXSuperscript(G4BestUnit(weight,"Mass"))          << "\t \\\\ "
00207          << std::endl;
00208   //  
00209   for(unsigned int iElement = 0; iElement<(unsigned int)lv->GetMaterial()->GetNumberOfElements(); iElement++) {
00210     // exclude Air in element weight fraction computation
00211     if(materialName.find("Air")) {
00212       std::string elementName = lv->GetMaterial()->GetElement(iElement)->GetName();
00213       double elementMassFraction = lv->GetMaterial()->GetFractionVector()[iElement];
00214       double elementWeight = weight*elementMassFraction;
00215       unsigned int elementIndex = (unsigned int)lv->GetMaterial()->GetElement(iElement)->GetIndex();
00216       elementNames[elementIndex]        = elementName;
00217       elementTotalWeight[elementIndex] += elementWeight;
00218     }
00219   }
00220 }
00221 
00222 void PrintMaterialBudgetInfo::dumpElementMassFraction(std::ostream& elementOut ) {
00223   // calculate mass fraction
00224   double totalWeight   = 0.0;
00225   double totalFraction = 0.0;
00226   for(unsigned int iElement = 0; iElement<(unsigned int)elementTotalWeight.size(); iElement++) {
00227     totalWeight+=elementTotalWeight[iElement];
00228   }
00229   // calculate element mass fractions
00230   for(unsigned int iElement = 0; iElement<(unsigned int)elementTotalWeight.size(); iElement++) {
00231     elementWeightFraction[iElement] = elementTotalWeight[iElement]/totalWeight;
00232     totalFraction+=elementWeightFraction[iElement];
00233   }
00234   // header
00235   elementOut << "Element"        << "\t\t"
00236              << "Index"          << "\t"
00237              << "Total Mass"     << "\t"
00238              << "Mass Fraction " << "\t"
00239              << std::endl;
00240   // dump
00241   for(unsigned int iElement = 0; iElement<(unsigned int)elementTotalWeight.size(); iElement++) {
00242     if(elementNames[iElement]!="rr") {
00243       if(elementNames[iElement].size()<8) elementNames[iElement].append("\t");
00244       elementOut << elementNames[iElement]                          << "\t"
00245                  << iElement                                        << "\t"
00246                  << G4BestUnit(elementTotalWeight[iElement],"Mass") << "\t"
00247                  << elementWeightFraction[iElement]
00248                  << std::endl;
00249     }
00250   }
00251   elementOut << "\n\t\tTotal Weight without Air " << G4BestUnit(totalWeight,"Mass")
00252              << "\tTotal Fraction "   << totalFraction
00253              << std::endl;
00254 }
00255 
00256 std::string PrintMaterialBudgetInfo::stringLaTeXUnderscore(std::string stringname) {
00257   // To replace '\' with '\_' to compile LaTeX output
00258   std::string stringoutput;
00259   
00260   for (unsigned int  i=0; i<stringname.length() ; i++) {
00261     if (stringname.substr(i,1) == "_") {
00262       stringoutput += "\\_";
00263     } else {
00264       stringoutput += stringname.substr(i,1);
00265     }
00266   }
00267   
00268   return stringoutput;
00269   
00270 }
00271 
00272 std::string PrintMaterialBudgetInfo::stringLaTeXSuperscript(std::string stringname) {
00273   // To replace 'm3' with 'm$^3$' to compile LaTeX output
00274   std::string stringoutput = stringname.substr(0,1);
00275   
00276   for (unsigned int  i=1; i<stringname.length() ; i++) {
00277     if (stringname.substr(i-1,1) == "m" && stringname.substr(i,1) == "3") {
00278       stringoutput += "$^3$";
00279     } else {
00280       stringoutput += stringname.substr(i,1);
00281     }
00282   }
00283     
00284   return stringoutput;
00285   
00286 }