Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-08-04 02:02:26

0001 #include <ostream>
0002 #include <string>
0003 #include <vector>
0004 
0005 #include "DetectorDescription/Core/interface/DDBase.h"
0006 #include "DetectorDescription/Core/interface/DDMaterial.h"
0007 #include "DetectorDescription/Core/interface/DDName.h"
0008 #include "DetectorDescription/Core/interface/Material.h"
0009 #include "DataFormats/Math/interface/GeantUnits.h"
0010 #include "FWCore/Utilities/interface/Exception.h"
0011 
0012 using DDI::Material;
0013 using namespace geant_units::operators;
0014 
0015 DDMaterial::DDMaterial() : DDBase<DDName, std::unique_ptr<Material>>() {}
0016 
0017 /**
0018    If a DDMaterial with \a name was already defined, this constructor creates a
0019    reference object to the defined material. Otherwise it creates a (default)
0020    initialized reference-object to a material with DDName \a name. 
0021       
0022    For further details concerning the usage of reference-objects refere
0023    to the documentation of DDLogicalPart.
0024 */
0025 DDMaterial::DDMaterial(const DDName &name) : DDBase<DDName, std::unique_ptr<Material>>() { create(name); }
0026 
0027 /** 
0028    \arg \c z atomic number
0029    \arg \c a atomic mass
0030    \arg \c density density
0031       
0032    Example:
0033    \code
0034      DDMaterial hydrogen("Hydrogen", 
0035                           double z=1, 
0036                       double a=1.1*g/mole, 
0037                           density=2*g/cm3);
0038    \endcode  
0039 */
0040 DDMaterial::DDMaterial(const DDName &name, double z, double a, double d) : DDBase<DDName, std::unique_ptr<Material>>() {
0041   create(name, std::make_unique<Material>(z, a, d));
0042 }
0043 
0044 /** 
0045    For a mixture material it is sufficient to specify the \a density of the
0046    mixture (in addition to the \a name). The compounds are added by
0047    using the addMaterial(..) method. 
0048      
0049    The result of this constructor is a reference-object. One can use the
0050    mixture material immidiately (without specifying the compund materials).
0051    Compound materials can be added at any later stage.
0052       
0053    For further details concerning the usage of reference-objects refere
0054    to the documentation of DDLogicalPart.      
0055 */
0056 DDMaterial::DDMaterial(const DDName &name, double density) : DDBase<DDName, std::unique_ptr<Material>>() {
0057   create(name, std::make_unique<Material>(0, 0, density));
0058 }
0059 
0060 /** 
0061   The fraction-masses of all compounds must sum up to 1
0062 */
0063 int DDMaterial::addMaterial(const DDMaterial &m, double fm) {
0064   if (m.ddname() == ddname()) {
0065     throw cms::Exception("DDException") << "DDMaterial::addMaterial(..): name-clash\n        trying to add material "
0066                                         << m << " to itself! ";
0067   }
0068   rep().addMaterial(m, fm);
0069   return rep().noOfConstituents();
0070 }
0071 
0072 int DDMaterial::noOfConstituents() const { return rep().noOfConstituents(); }
0073 
0074 DDMaterial::FractionV::value_type DDMaterial::constituent(int i) const { return rep().constituent(i); }
0075 
0076 double DDMaterial::a() const { return rep().a(); }
0077 
0078 double DDMaterial::z() const { return rep().z(); }
0079 
0080 double DDMaterial::density() const { return rep().density(); }
0081 
0082 namespace {
0083   std::ostream &doStream(std::ostream &os, const DDMaterial &mat, int level) {
0084     ++level;
0085     if (mat) {
0086       os << '[' << mat.name() << ']' << " z=" << mat.z() << " a=" << convertUnitsTo(1._g_per_mole, mat.a()) << "*g/mole"
0087          << " d=" << convertUnitsTo(1._g_per_cm3, mat.density()) << "*g/cm3";
0088       std::string s(2 * level, ' ');
0089       for (int i = 0; i < mat.noOfConstituents(); ++i) {
0090         DDMaterial::FractionV::value_type f = mat.constituent(i);
0091         os << std::endl << s << i + 1 << " : fm=" << f.second << " : ";
0092         doStream(os, f.first, level);
0093       }
0094     } else
0095       os << "* material not declared * ";
0096     --level;
0097     return os;
0098   }
0099 }  // namespace
0100 
0101 std::ostream &operator<<(std::ostream &os, const DDMaterial &mat) { return doStream(os, mat, 0); }