ATLAS Offline Software
Loading...
Searching...
No Matches
InDetMaterialManager Class Reference

InDetMaterialManager. More...

#include <InDetMaterialManager.h>

Inheritance diagram for InDetMaterialManager:
Collaboration diagram for InDetMaterialManager:

Classes

class  MaterialByWeight
class  MaterialComponent
class  MaterialDef
 Class to hold information need to create a material. More...

Public Member Functions

 InDetMaterialManager (const std::string &managerName, StoreGateSvc *detStore)
 InDetMaterialManager (const std::string &managerName, StoreGateSvc *detStore, const IRDBRecordset_ptr &weightTable, const std::string &space="", bool extraFunctionality=false)
 InDetMaterialManager (const std::string &managerName, StoreGateSvc *detStore, const IRDBRecordset_ptr &weightTable, const IRDBRecordset_ptr &compositionTable, const std::string &space="")
 InDetMaterialManager (const std::string &managerName, InDetDD::AthenaComps *)
 ~InDetMaterialManager ()
void addWeightTable (const IRDBRecordset_ptr &weightTable, const std::string &space="")
void addWeightMaterial (const std::string &materialName, const std::string &materialBase, double weight, int linearWeightFlag)
void addCompositionTable (const IRDBRecordset_ptr &compositionTable, const std::string &space="")
void addScalingTable (const IRDBRecordset_ptr &scalingTable)
bool hasMaterial (const std::string &materialName) const
const GeoMaterial * getMaterial (std::string_view materialName)
 Get material. First looks for locally defined material and if not found looks in GeoModel material manager.
const GeoElement * getElement (const std::string &elementName)
 Get element from GeoModel material manager.
const GeoMaterial * getMaterial (std::string_view origMaterialName, double density, std::string_view newName={})
 Create and get material with a specified density based on an existing material.
const GeoMaterial * getMaterialScaled (const std::string &origMaterialName, double scaleFactor, const std::string &newName="")
const GeoMaterial * getMaterialForVolume (std::string_view materialName, double volume, std::string_view newName={})
 Create and get material with a density calculated to give weight in predefined weight table.
const GeoMaterial * getMaterialForVolumeLength (const std::string &materialName, double volume, double length, const std::string &newName="")
const GeoMaterial * getMaterialForVolumeLength (const std::string &name, const std::vector< std::string > &materialComponents, const std::vector< double > &factors, double volume, double length)
const GeoMaterial * getMaterialForVolumeLength (const std::string &name, const std::string &materialComponent, double factor, double volume, double length)
const GeoMaterial * getCompositeMaterialForVolume (const std::string &newMatName, const double volumeTot, const double volume1, const std::string &matName1, const double volume2, const std::string &matName2)
const GeoMaterial * getMaterial (const std::string &name, const std::vector< std::string > &materialComponents, const std::vector< double > &fractWeights, double density)
void addMaterial (GeoMaterial *material)
 Add material.
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Private Types

using MaterialStore = std::map<std::string, GeoIntrusivePtr<const GeoMaterial>, std::less<>>
typedef std::map< std::string, MaterialByWeight, std::less<> > MaterialWeightMap
typedef std::map< std::string, MaterialComponent, std::less<> > MaterialCompositionMap
typedef std::map< std::string, double, std::less<> > ExtraScaleFactorMap

Private Member Functions

StoredMaterialManagerretrieveManager (const StoreGateSvc *detStore)
const GeoMaterial * getAdditionalMaterial (std::string_view materialName) const
bool compareDensity (double d1, double d2) const
const GeoMaterial * getMaterialInternal (std::string_view materialName)
const GeoMaterial * getMaterialInternal (std::string_view origMaterialName, double density, std::string_view newName={})
const GeoMaterial * getMaterialScaledInternal (const std::string &origMaterialName, double scaleFactor, const std::string &newName="")
const GeoMaterial * getMaterialInternal (const std::string &name, const std::vector< std::string > &materialComponents, const std::vector< double > &fractWeights, double density)
const GeoMaterial * extraScaledMaterial (std::string_view materialName, std::string_view newName, const GeoMaterial *origMaterial)
const GeoMaterial * extraScaledMaterial (std::string_view materialName, const GeoMaterial *origMaterial)
void createMaterial (const MaterialDef &material)
double getExtraScaleFactor (std::string_view materialName)
void initMessaging () const
 Initialize our message level and MessageSvc.

Private Attributes

StoredMaterialManagerm_materialManager
std::string m_managerName
MaterialStore m_store
MaterialWeightMap m_weightMap
MaterialCompositionMap m_matCompositionMap
ExtraScaleFactorMap m_scalingMap
bool m_extraFunctionality
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels).
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging).

Detailed Description

InDetMaterialManager.

This provides an interface to the GeoModel Material Manager as well as allowing additional materials to be defined or standard ones redefined. It also allows creating new materials based on existing ones but with a different density. It is also possible to specify a weight table and this is used to create materials with a density such that the the total weight is correct.

Definition at line 33 of file InDetMaterialManager.h.

Member Typedef Documentation

◆ ExtraScaleFactorMap

typedef std::map<std::string, double, std::less<> > InDetMaterialManager::ExtraScaleFactorMap
private

Definition at line 221 of file InDetMaterialManager.h.

◆ MaterialCompositionMap

typedef std::map<std::string, MaterialComponent, std::less<> > InDetMaterialManager::MaterialCompositionMap
private

Definition at line 218 of file InDetMaterialManager.h.

◆ MaterialStore

using InDetMaterialManager::MaterialStore = std::map<std::string, GeoIntrusivePtr<const GeoMaterial>, std::less<>>
private

Definition at line 212 of file InDetMaterialManager.h.

◆ MaterialWeightMap

typedef std::map<std::string, MaterialByWeight, std::less<> > InDetMaterialManager::MaterialWeightMap
private

Definition at line 215 of file InDetMaterialManager.h.

Constructor & Destructor Documentation

◆ InDetMaterialManager() [1/4]

InDetMaterialManager::InDetMaterialManager ( const std::string & managerName,
StoreGateSvc * detStore )

Definition at line 28 of file InDetMaterialManager.cxx.

30 : AthMessaging(managerName),
31 m_managerName(managerName),
33{
35}
AthMessaging()
Default constructor:
StoredMaterialManager * retrieveManager(const StoreGateSvc *detStore)
StoredMaterialManager * m_materialManager

◆ InDetMaterialManager() [2/4]

InDetMaterialManager::InDetMaterialManager ( const std::string & managerName,
StoreGateSvc * detStore,
const IRDBRecordset_ptr & weightTable,
const std::string & space = "",
bool extraFunctionality = false )

Definition at line 38 of file InDetMaterialManager.cxx.

43 : AthMessaging(managerName),
44 m_managerName(managerName),
45 m_extraFunctionality(extraFunctionality)
46{
48
49 if (weightTable) addWeightTable(weightTable, space);
50
51 // For testing we add a few materials.
52 //m_weightMap["sct::CoolingBlock"] = MaterialByWeight(2.418*CLHEP::gram);
53 //m_weightMap["sct::CoolingBlock"] = MaterialByWeight(2*CLHEP::gram);
54 //m_weightMap["sct::BrlHybrid"] = MaterialByWeight("sct::Hybrid", 8*CLHEP::gram);
55 //m_weightMap["sct::FwdHybrid"] = MaterialByWeight("std::Carbon", 7.662*CLHEP::gram);
56}
void addWeightTable(const IRDBRecordset_ptr &weightTable, const std::string &space="")

◆ InDetMaterialManager() [3/4]

InDetMaterialManager::InDetMaterialManager ( const std::string & managerName,
StoreGateSvc * detStore,
const IRDBRecordset_ptr & weightTable,
const IRDBRecordset_ptr & compositionTable,
const std::string & space = "" )

Definition at line 58 of file InDetMaterialManager.cxx.

62 : AthMessaging(managerName),
63 m_managerName(managerName),
65{
67
68 if (weightTable) addWeightTable(weightTable, space);
69 if (compositionTable) addCompositionTable(compositionTable, space);
70}
void addCompositionTable(const IRDBRecordset_ptr &compositionTable, const std::string &space="")

◆ InDetMaterialManager() [4/4]

InDetMaterialManager::InDetMaterialManager ( const std::string & managerName,
InDetDD::AthenaComps * athenaComps )

Definition at line 72 of file InDetMaterialManager.cxx.

74 : AthMessaging(managerName),
75 m_managerName(managerName),
77{
79}
const StoreGateSvc * detStore() const

◆ ~InDetMaterialManager()

InDetMaterialManager::~InDetMaterialManager ( )
default

Member Function Documentation

◆ addCompositionTable()

void InDetMaterialManager::addCompositionTable ( const IRDBRecordset_ptr & compositionTable,
const std::string & space = "" )

Definition at line 389 of file InDetMaterialManager.cxx.

389 {
390 ATH_MSG_DEBUG("Reading in composition table: " << compositionTable->nodeName());
391
392 for (const auto& rec : *compositionTable) {
393 std::string materialName = rec->getString("MATERIAL");
394 if (!space.empty()) {
395 materialName = space + "::" + materialName;
396 }
397
398 std::string componentName = rec->getString("COMPONENT");
399 int count = rec->getInt("COUNT");
400 double factor = rec->getDouble("FACTOR");
401 double actualLength = rec->getDouble("ACTUALLENGTH");
402
403 m_matCompositionMap.insert(std::pair<std::string, MaterialComponent>(materialName,
404 MaterialComponent(componentName,
405 count * factor,
406 actualLength)));
407 }
408}
#define ATH_MSG_DEBUG(x)
virtual std::string nodeName() const =0
MaterialCompositionMap m_matCompositionMap
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148

◆ addMaterial()

void InDetMaterialManager::addMaterial ( GeoMaterial * material)

Add material.

Definition at line 302 of file InDetMaterialManager.cxx.

302 {
303 GeoIntrusivePtr<const GeoMaterial> matPtr{material};
304 std::string name(material->getName());
305 if (m_store.find(name) != m_store.end()) {
306 ATH_MSG_WARNING("Ignoring attempt to redefine an existing material: " << name);
307 // Delete the material if it is not already ref counted.
308 //std::cout << m_store[name] << std::endl;
309 } else {
310 material->lock();
311 m_store[name] = std::move(matPtr);
312
313 ATH_MSG_DEBUG("Created new material: " << name << ", " << material->getDensity() /
314 (Gaudi::Units::g / Gaudi::Units::cm3) << " g/cm3");
315 }
316}
#define ATH_MSG_WARNING(x)

◆ addScalingTable()

void InDetMaterialManager::addScalingTable ( const IRDBRecordset_ptr & scalingTable)

Definition at line 411 of file InDetMaterialManager.cxx.

411 {
412 if (!scalingTable || scalingTable->size()==0) return;
413 ATH_MSG_DEBUG("Reading in extra material scaling table: " << scalingTable->nodeName());
414 for (const auto& rec : *scalingTable) {
415 std::string materialName = rec->getString("MATERIAL");
416 double scalingFactor = rec->getDouble("FACTOR");
417
418 if (scalingFactor >= 0 || scalingFactor == 1) {
419 ATH_MSG_DEBUG("Material " << materialName << " will be scaled by: " << scalingFactor);
420 } else {
421 // -ve or scalefactor = 1 means will not be scaled.
422 ATH_MSG_DEBUG("Material " << materialName << " will be NOT be scaled.");
423 }
424 if (m_scalingMap.find(materialName) != m_scalingMap.end()) {
425 ATH_MSG_WARNING("Overriding material: " << materialName << " which already exists in scaling table");
426 }
427 m_scalingMap[materialName] = scalingFactor;
428 }
429}
virtual unsigned int size() const =0
ExtraScaleFactorMap m_scalingMap

◆ addWeightMaterial()

void InDetMaterialManager::addWeightMaterial ( const std::string & materialName,
const std::string & materialBase,
double weight,
int linearWeightFlag )

Definition at line 372 of file InDetMaterialManager.cxx.

373 {
374 // Weight in gr
375 weight = weight * GeoModelKernelUnits::gram;
376
377 if (m_weightMap.find(materialName) != m_weightMap.end()) {
378 ATH_MSG_WARNING("Material: " << materialName << " already exists in weight table");
379 } else {
380 ATH_MSG_DEBUG("Adding " << materialName
381 << " weight " << weight
382 << " linearWeightFlag " << linearWeightFlag
383 << " to weight table");
384 m_weightMap[materialName] = MaterialByWeight(materialBase, weight, linearWeightFlag);
385 }
386}
MaterialWeightMap m_weightMap

◆ addWeightTable()

void InDetMaterialManager::addWeightTable ( const IRDBRecordset_ptr & weightTable,
const std::string & space = "" )

Definition at line 327 of file InDetMaterialManager.cxx.

327 {
328 ATH_MSG_DEBUG("Reading in weight table: " << weightTable->nodeName());
329 for(const auto& rec : *weightTable) {
330 std::string materialName = rec->getString("MATERIAL");
331 if (!space.empty()) {
332 materialName = space + "::" + materialName;
333 }
334 std::string materialBase;
335 try {
336 if (!rec->isFieldNull("BASEMATERIAL")) {
337 materialBase = rec->getString("BASEMATERIAL");
338 }
339 }
340 catch(std::runtime_error&) {
341 ATH_MSG_DEBUG(weightTable->nodeName() << " table has no column named BASEMATERIAL");
342 }
343 double weight = rec->getDouble("WEIGHT") * GeoModelKernelUnits::gram;
344
345 bool linearWeightFlag = false;
347 try {
348 if(!rec->isFieldNull("LINWEIGHTFLAG")) {
349 linearWeightFlag = rec->getInt("LINWEIGHTFLAG");
350 }
351 }
352 catch(std::runtime_error&) {
353 ATH_MSG_DEBUG(weightTable->nodeName() << " table has no column named LINWEIGHTFLAG");
354 }
355 }
356
357 if (m_weightMap.find(materialName) != m_weightMap.end()) {
358 ATH_MSG_WARNING("Material: " << materialName << " already exists in weight table");
359 } else {
360 ATH_MSG_DEBUG("Adding " << materialName
361 << " weight " << weight
362 << " linearWeightFlag " << linearWeightFlag
363 << " raw weight " << rec->getDouble("WEIGHT")
364 << " m_extraFunctionality " << m_extraFunctionality
365 << " to weight table");
366 m_weightMap[materialName] = MaterialByWeight(materialBase, weight, linearWeightFlag);
367 }
368 }
369}

◆ compareDensity()

bool InDetMaterialManager::compareDensity ( double d1,
double d2 ) const
private

Definition at line 319 of file InDetMaterialManager.cxx.

319 {
320 if (close_to_zero(d2)){
321 throw (std::runtime_error("InDetMaterialManager:compareDensity: Density is zero"));
322 }
323 return(std::abs(d1 / d2 - 1.) < 1e-5);
324}
bool close_to_zero(T value, T eps=std::numeric_limits< T >::epsilon())

◆ createMaterial()

void InDetMaterialManager::createMaterial ( const MaterialDef & material)
private

Definition at line 697 of file InDetMaterialManager.cxx.

697 {
698 if (material.numComponents() == 0) {
699 ATH_MSG_ERROR("Material has no components: " << material.name());
700 return;
701 }
702
703 // If total of fractions is greater than 1.1 then assume material is define by ratio of atoms.
704 double totWeight = material.totalFraction();
705 bool byAtomicRatio = false;
706 if (totWeight > 1.1) {
707 byAtomicRatio = true;
708 for (unsigned int i = 0; i < material.numComponents(); i++) {
709 if (material.compName(i).find("::") != std::string::npos) {
710 // If component name has "::" in it then its not an element.
711 ATH_MSG_ERROR("Material, " << material.name() <<
712 ", is assumed to be defined by atomic ratio (due to total fraction > 1)"
713 " but component is not an element: " << material.compName(i));
714 return;
715 }
716 const GeoElement* element = getElement(material.compName(i));
717 if (!element) {
718 ATH_MSG_ERROR("Error making material " << material.name() << ". Element not found: " <<
719 material.compName(i));
720 return;
721 }
722 totWeight += material.fraction(i) * element->getA();
723 }
724 } else {
725 // Check if total fraction is close to 1.
726 if (std::abs(totWeight - 1) > 0.01) {
727 ATH_MSG_WARNING("Total fractional weight does not sum to 1. Will renormalize. Total = " << totWeight);
728 }
729 }
730 // Now build the material
731 GeoIntrusivePtr<GeoMaterial> newMaterial{new GeoMaterial(material.name(), material.density())};
732 ATH_MSG_DEBUG("Creating material: " << material.name() << " with density: "
733 << material.density() / (Gaudi::Units::g / Gaudi::Units::cm3));
734 if (close_to_zero(totWeight)){
735 ATH_MSG_ERROR("totWeight is zero in InDetMaterialManager::createMaterial");
736 return;
737 }
738 for (unsigned int i = 0; i < material.numComponents(); i++) {
739 double fracWeight = material.fraction(i) / totWeight;
740 if (material.compName(i).find("::") == std::string::npos) {
741 const GeoElement* element = getElement(material.compName(i));
742 if (!element) {
743 ATH_MSG_ERROR("Error making material " << material.name() << ". Element not found: " << material.compName(i));
744 // delete the partially created material
745 return;
746 }
747 if (byAtomicRatio) {
748 fracWeight = material.fraction(i) * element->getA() / totWeight;
749 }
750 newMaterial->add(const_cast<GeoElement*>(element), fracWeight);
751 ATH_MSG_DEBUG(" Component: " << material.compName(i) << " " << fracWeight);
752 } else {
753 GeoIntrusivePtr<const GeoMaterial> materialTmp{getMaterialInternal(material.compName(i))};
754 if (!materialTmp) {
755 ATH_MSG_ERROR("Error making material " << material.name() << ". Component not found: " << material.compName(i));
756 // delete the partially created material
757 return;
758 }
759 if (byAtomicRatio) {
760 // Should not happen as already checked that all components were elements.
761 ATH_MSG_ERROR("Unexpected Error");
762 }
763 newMaterial->add(const_cast<GeoMaterial*>(materialTmp.get()), fracWeight);
764 ATH_MSG_DEBUG(" Component: " << material.compName(i) << " " << fracWeight);
765 }
766 }
767 newMaterial->lock();
768 addMaterial(newMaterial);
769}
#define ATH_MSG_ERROR(x)
const GeoElement * getElement(const std::string &elementName)
Get element from GeoModel material manager.
void addMaterial(GeoMaterial *material)
Add material.
const GeoMaterial * getMaterialInternal(std::string_view materialName)

◆ extraScaledMaterial() [1/2]

const GeoMaterial * InDetMaterialManager::extraScaledMaterial ( std::string_view materialName,
const GeoMaterial * origMaterial )
private

Definition at line 817 of file InDetMaterialManager.cxx.

817 {
818 if (!origMaterial) throw std::runtime_error(std::format("Invalid material: {}",materialName));
819
820 double scaleFactor = getExtraScaleFactor(materialName);
821 // -1 (or any -ve number) indicates material is not scaled. And if the scale factor
822 // is 1 then there is no need to create a new material.
823 if (scaleFactor < 0 || scaleFactor == 1 || materialName.find("Ether") != std::string::npos) return origMaterial;
824
825 if (scaleFactor == 0) return getMaterialInternal("std::Vacuum");
826
827 std::string newName = std::string{materialName} + "_ExtraScaling";
828
829 // Check if it is already made.
830 const GeoMaterial* newMaterial = getAdditionalMaterial(newName);
831
832 // Already made so we return it.
833 if (newMaterial) return newMaterial;
834
835 // Otherwise we need to make it.
836 double density = origMaterial->getDensity() * scaleFactor;
837
838 // create new material
839 GeoMaterial* newMaterialTmp = new GeoMaterial(newName, density);
840 newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), 1.);
841 addMaterial(newMaterialTmp);
842 newMaterial = newMaterialTmp;
843
844 return newMaterial;
845}
const GeoMaterial * getAdditionalMaterial(std::string_view materialName) const
double getExtraScaleFactor(std::string_view materialName)

◆ extraScaledMaterial() [2/2]

const GeoMaterial * InDetMaterialManager::extraScaledMaterial ( std::string_view materialName,
std::string_view newName,
const GeoMaterial * origMaterial )
private

Definition at line 806 of file InDetMaterialManager.cxx.

808 {
809 if (newName.empty()) {
810 return extraScaledMaterial(materialName, origMaterial);
811 } else {
812 return extraScaledMaterial(newName, origMaterial);
813 }
814}
const GeoMaterial * extraScaledMaterial(std::string_view materialName, std::string_view newName, const GeoMaterial *origMaterial)

◆ getAdditionalMaterial()

const GeoMaterial * InDetMaterialManager::getAdditionalMaterial ( std::string_view materialName) const
private

Definition at line 127 of file InDetMaterialManager.cxx.

127 {
128 MaterialStore::const_iterator iter;
129 if ((iter = m_store.find(materialName)) != m_store.end()) {
130 return iter->second;
131 } else {
132 return nullptr;
133 }
134}

◆ getCompositeMaterialForVolume()

const GeoMaterial * InDetMaterialManager::getCompositeMaterialForVolume ( const std::string & newMatName,
const double volumeTot,
const double volume1,
const std::string & matName1,
const double volume2,
const std::string & matName2 )

Definition at line 137 of file InDetMaterialManager.cxx.

141 {
142 std::vector<std::string> baseMaterials;
143 std::vector<double> fracWeight;
144 baseMaterials.reserve(2);
145 fracWeight.reserve(2);
146
147 ATH_MSG_DEBUG("Composite material : " << volumeTot / Gaudi::Units::cm3 << " = " << volume1 / Gaudi::Units::cm3
148 << " + " << volume2 / Gaudi::Units::cm3);
149 ATH_MSG_DEBUG("Composite material : " << matName1 << " " << matName2);
150
151 double density1, density2;
152
153 MaterialWeightMap::const_iterator iter;
154 if ((iter = m_weightMap.find(matName1)) != m_weightMap.end()) {
155 const GeoMaterial* mat1 = getMaterialForVolume(matName1, volume1);
156 density1 = mat1->getDensity();
157 ATH_MSG_DEBUG("Composite material 1 - weight : " << density1 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
158 } else {
159 const GeoMaterial* mat1 = getMaterial(matName1);
160 density1 = mat1->getDensity();
161 ATH_MSG_DEBUG("Composite material 1 - standard : " << density1 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
162 }
163
164 if ((iter = m_weightMap.find(matName2)) != m_weightMap.end()) {
165 const GeoMaterial* mat2 = getMaterialForVolume(matName2, volume2);
166 density2 = mat2->getDensity();
167 ATH_MSG_DEBUG("Composite material 2 - weight : " << density2 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
168 } else {
169 const GeoMaterial* mat2 = getMaterial(matName2);
170 density2 = mat2->getDensity();
171 ATH_MSG_DEBUG("Composite material 2 - standard : " << density2 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
172 }
173
174 double weight1 = density1 * volume1;
175 double weight2 = density2 * volume2;
176 double invWeightTot = 1.0 / (weight1 + weight2);
177
178 double density = (weight1 + weight2) / volumeTot;
179
180 double frac1 = weight1 / (weight1 + weight2);
181 double frac2 = weight2 / (weight1 + weight2);
182 double density_2 = 1.0 / (frac1 / density1 + frac2 / density2);
183 double density_3 = (weight1 + weight2) / (volume1 + volume2);
184 ATH_MSG_DEBUG("-> weights : " << weight1 / (GeoModelKernelUnits::gram) << " " << weight2 / (GeoModelKernelUnits::gram));
185 ATH_MSG_DEBUG("-> density : " << density / (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << " " << density_2 /
186 (GeoModelKernelUnits::gram / Gaudi::Units::cm3) << " " << density_3 / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
187
188
189 baseMaterials.push_back(matName1);
190 baseMaterials.push_back(matName2);
191 fracWeight.push_back(weight1 * invWeightTot);
192 fracWeight.push_back(weight2 * invWeightTot);
193
194 return getMaterial(newMatName, baseMaterials, fracWeight, density);
195}
const GeoMaterial * getMaterialForVolume(std::string_view materialName, double volume, std::string_view newName={})
Create and get material with a density calculated to give weight in predefined weight table.
const GeoMaterial * getMaterial(std::string_view materialName)
Get material. First looks for locally defined material and if not found looks in GeoModel material ma...

◆ getElement()

const GeoElement * InDetMaterialManager::getElement ( const std::string & elementName)

Get element from GeoModel material manager.

Definition at line 89 of file InDetMaterialManager.cxx.

89 {
91 std::string errorMessage("Null pointer to Stored Material Manager!");
92 ATH_MSG_FATAL(errorMessage);
93 throw std::runtime_error(errorMessage);
94 }
95 return m_materialManager->getElement(elementName);
96}
#define ATH_MSG_FATAL(x)

◆ getExtraScaleFactor()

double InDetMaterialManager::getExtraScaleFactor ( std::string_view materialName)
private

Definition at line 848 of file InDetMaterialManager.cxx.

848 {
849 // If name is found in map we return the corresponding scale factor.
850 // The special name "ALL" indicates all materials are scaled.
851 // Individual materials can be excluded from scaling by giving either
852 // a -ve scaling factor or just specifying a scaling factor of 1.
853 // A scaling factor of 0 means the material will be replaced by vacuum.
854
855 ExtraScaleFactorMap::const_iterator iter = m_scalingMap.find(materialName);
856 if (iter != m_scalingMap.end()) {
857 return iter->second;
858 } else {
859 // Check for special names
860 // ALL means everything scaled. Do not scale air or vacuum (unless explicity requested)
861 iter = m_scalingMap.find("ALL");
862 if (iter != m_scalingMap.end() && materialName != "std::Air" && materialName != "std::Vacuum") {
863 return iter->second;
864 }
865 }
866
867 // If not found then return -1 to indicate material is not to be scaled.
868 return -1;
869}

◆ getMaterial() [1/3]

const GeoMaterial * InDetMaterialManager::getMaterial ( const std::string & name,
const std::vector< std::string > & materialComponents,
const std::vector< double > & fractWeights,
double density )

Definition at line 658 of file InDetMaterialManager.cxx.

661 {
662 return extraScaledMaterial(name, getMaterialInternal(name, materialComponents, fracWeight, density));
663}

◆ getMaterial() [2/3]

const GeoMaterial * InDetMaterialManager::getMaterial ( std::string_view materialName)

Get material. First looks for locally defined material and if not found looks in GeoModel material manager.

Definition at line 99 of file InDetMaterialManager.cxx.

99 {
100 return extraScaledMaterial(materialName, getMaterialInternal(materialName));
101}

◆ getMaterial() [3/3]

const GeoMaterial * InDetMaterialManager::getMaterial ( std::string_view origMaterialName,
double density,
std::string_view newName = {} )

Create and get material with a specified density based on an existing material.

If a newName is supplied it creates the new material even if the orginal material has the same density. It however first checks if the material with NewName exists. If no newName is supplied then it checks the density of the existing material. If it is consistent it returns the material. If it is different it creates a material with the string "Modified" added to the name.

Definition at line 209 of file InDetMaterialManager.cxx.

211 {
212 return extraScaledMaterial(origMaterialName, newName,
213 getMaterialInternal(origMaterialName, density, newName));
214}

◆ getMaterialForVolume()

const GeoMaterial * InDetMaterialManager::getMaterialForVolume ( std::string_view materialName,
double volume,
std::string_view newName = {} )

Create and get material with a density calculated to give weight in predefined weight table.

Definition at line 432 of file InDetMaterialManager.cxx.

432 {
433 // Make sure we have a valid volume size.
434 if (volume <= 0) {
435 ATH_MSG_ERROR("Invalid volume : " << volume);
436 return nullptr;
437 }
438
439 // Find if material is in the weight table.
440 // If so we use the information to create a material with the
441 // density calculated from the volume and weight. If a base material
442 // is specified in the weight table, then a new material is made
443 // which is the same as the base material but with the new
444 // density. If no base material is specified then there should be a
445 // material already existing with that name. If the existing material already has the
446 // correct density it is used, otherwise a new material is created
447 // with the string "Modified" added to the material name.
448
449 MaterialWeightMap::const_iterator iter;
450 if (iter = m_weightMap.find(materialName); iter != m_weightMap.end()) {
451 const std::string& materialBase = iter->second.name;
452 double weight = iter->second.weight;
453 double density = weight / volume;
454 if (iter->second.linearWeightFlag) {
455 ATH_MSG_ERROR("Material defined by linear weight cannot be created with getMaterialForVolume method: " <<
456 materialName);
457 }
458
459 ATH_MSG_VERBOSE("Found material in weight table - name, base, weight(g), volume(cm3), density(g/cm3): "
460 << materialName << ", "
461 << materialBase << ", "
462 << weight / GeoModelKernelUnits::gram << ", "
463 << volume / Gaudi::Units::cm3 << ", "
464 << density / (Gaudi::Units::g / Gaudi::Units::cm3));
465
466 if (materialBase.empty()) {
467 return getMaterial(materialName, density, newName);
468 } else {
469 if (newName.empty()) {
470 return getMaterial(materialBase, density, materialName);
471 } else {
472 return getMaterial(materialBase, density, newName);
473 }
474 }
475 } else {
476 // If not in the weight table we just return the material.
477 // This is not an error.
478 ATH_MSG_VERBOSE("Material not in weight table, using standard material: "
479 << materialName
480 << ", volume(cm3) = " << volume / Gaudi::Units::cm3);
481 return getMaterial(materialName);
482 }
483}
#define ATH_MSG_VERBOSE(x)

◆ getMaterialForVolumeLength() [1/3]

const GeoMaterial * InDetMaterialManager::getMaterialForVolumeLength ( const std::string & materialName,
double volume,
double length,
const std::string & newName = "" )

Definition at line 486 of file InDetMaterialManager.cxx.

487 {
488 // In the case there is no material composition table (MaterialCompositionMap) and no linear weights are used this
489 // will
490 // behave the same way as getMaterialForVolume.
491 // If the material is in the MaterialCompositionMap it will build a material using the components
492 // from that table. If any components are defined as a linear weight the length is used to calculate the
493 // weight (ie linear weight * length).
494
495
496 std::string name;
497 if (newName.empty()) {
498 name = materialName;
499 } else {
500 name = newName;
501 }
502
503 // Make sure we have a valid volume size.
504 if (volume <= 0 || length <= 0) {
505 ATH_MSG_ERROR("Invalid volume or length : " << volume << ", " << length);
506 return nullptr;
507 }
508
509 // First look in the predefinded collections
510 std::pair<MaterialCompositionMap::const_iterator, MaterialCompositionMap::const_iterator> iterRange;
511 iterRange = m_matCompositionMap.equal_range(materialName);
512 if (iterRange.first != m_matCompositionMap.end()) {
513 ATH_MSG_VERBOSE("Found material in material composition table:" << materialName);
514
515 std::vector<double> factors;
516 std::vector<std::string> components;
517 for (MaterialCompositionMap::const_iterator iter = iterRange.first; iter != iterRange.second; ++iter) {
518 double factorTmp = iter->second.factor;
519 if (iter->second.actualLength > 0) factorTmp *= iter->second.actualLength / length;
520 factors.push_back(factorTmp);
521 components.push_back(iter->second.name);
522 }
523 return getMaterialForVolumeLength(name, components, factors, volume, length);
524 }
525
526 // Next look in weight table
527 MaterialWeightMap::const_iterator iter;
528 if ((iter = m_weightMap.find(materialName)) != m_weightMap.end()) {
529 const std::string& materialBase = iter->second.name;
530 double weight = iter->second.weight;
531 double density = weight / volume;
532 if (iter->second.linearWeightFlag) weight *= length;
533
534 if (materialBase.empty()) {
535 return getMaterial(materialName, density, newName);
536 } else {
537 return getMaterial(materialBase, density, name);
538 }
539 } else {
540 // Otherwise we just return the material.
541 // This is not an error.
542 ATH_MSG_VERBOSE("Material not in weight table, using standard material: "
543 << materialName
544 << ", volume(cm3) = " << volume / Gaudi::Units::cm3);
545 return getMaterial(materialName);
546 }
547}
double length(const pvec &v)
const GeoMaterial * getMaterialForVolumeLength(const std::string &materialName, double volume, double length, const std::string &newName="")

◆ getMaterialForVolumeLength() [2/3]

const GeoMaterial * InDetMaterialManager::getMaterialForVolumeLength ( const std::string & name,
const std::string & materialComponent,
double factor,
double volume,
double length )

Definition at line 550 of file InDetMaterialManager.cxx.

554 {
555 std::vector<std::string> tmpMaterialComponents(1, materialComponent);
556 std::vector<double> tmpFactors(1, factor);
557 return getMaterialForVolumeLength(name, tmpMaterialComponents, tmpFactors, volume, length);
558}

◆ getMaterialForVolumeLength() [3/3]

const GeoMaterial * InDetMaterialManager::getMaterialForVolumeLength ( const std::string & name,
const std::vector< std::string > & materialComponents,
const std::vector< double > & factors,
double volume,
double length )

Definition at line 561 of file InDetMaterialManager.cxx.

565 {
566 // Make sure we have a valid volume size.
567 if (volume <= 0 || length <= 0) {
568 ATH_MSG_ERROR("Invalid volume or length : " << volume << ", " << length);
569 return nullptr;
570 }
571
572 if (!factors.empty() && factors.size() < materialComponents.size()) {
573 ATH_MSG_WARNING("getMaterialForVolumeLength: factor vector size too small. Setting remaining factors to 1.");
574 }
575
576 std::vector<std::string> baseMaterials;
577 std::vector<double> fracWeight;
578 baseMaterials.reserve(materialComponents.size());
579 fracWeight.reserve(materialComponents.size());
580
581 double totWeight = 0;
582 for (unsigned int iComp = 0; iComp < materialComponents.size(); ++iComp) {
583 const std::string& materialName = materialComponents[iComp];
584
585 // First search in MaterialWeightMap
586 MaterialWeightMap::const_iterator iter;
587 if ((iter = m_weightMap.find(materialName)) != m_weightMap.end()) {
588 const std::string& materialBase = iter->second.name;
589 double weight = iter->second.weight;
590
591 if (iComp < factors.size()) {
592 weight *= factors[iComp];
593 }
594 ATH_MSG_DEBUG("Material " << materialName
595 << " found in weight table, weight " << iter->second.weight / GeoModelKernelUnits::gram
596 << " factor " << factors[iComp]
597 << " w*fac*len " << weight * length / GeoModelKernelUnits::gram
598 << " basMat " << materialBase
599 << " linear? " << iter->second.linearWeightFlag);
600
601 if (iter->second.linearWeightFlag) weight *= length;
602 if (materialBase.empty()) {
603 // If no base material then name should refer to an already defined material
604 baseMaterials.push_back(materialName);
605 } else {
606 baseMaterials.push_back(materialBase);
607 }
608 fracWeight.push_back(weight); // Will be normalized later.
609 totWeight += weight;
610 } else {
611 // If not in the weight table we look for a regular material.
612 // I don't think this would normally be intentional so we give a warning message.
613 /*
614 if (msgLvl(MSG::WARNING))
615 msg(MSG::WARNING)
616 << "Component material not in weight table, using standard material: "
617 << materialName << " with weight= "
618 << factors.at(iComp) * length
619 << endmsg;
620 const GeoMaterial * material = getMaterialInternal(materialName);
621 */
622
623 // In this case the factor should correspond to the linear weight
624 double weight = factors.at(iComp) * length * GeoModelKernelUnits::gram;
625
626 // If material not found, will get error message when attempting to make the material. So carry on here.
627 baseMaterials.push_back(materialName);
628 fracWeight.push_back(weight);
629 totWeight += weight;
630 }
631 }
632
633 if (msgLvl(MSG::VERBOSE)) {
634 msg(MSG::VERBOSE) << "Creating material from multiple components: " << name << endmsg;
635 for (unsigned int i = 0; i < materialComponents.size(); ++i) {
636 msg(MSG::VERBOSE) << " Component " << i << ": Name = " << baseMaterials[i]
637 << " Weight(g) = " << fracWeight[i] / Gaudi::Units::g << endmsg;
638 }
639 }
640 if (close_to_zero(totWeight)){
641 ATH_MSG_ERROR("totWeight is zero in InDetMaterialManager::getMaterialForVolumeLength");
642 return nullptr;
643 }
644 for (unsigned int i = 0; i < fracWeight.size(); ++i) {
645 fracWeight[i] /= totWeight;
646 }
647 if (close_to_zero(volume)){
648 ATH_MSG_ERROR("volume is zero in InDetMaterialManager::getMaterialForVolumeLength");
649 return nullptr;
650 }
651 double density = totWeight / volume;
652
653 return getMaterial(name, baseMaterials, fracWeight, density);
654}
#define endmsg
MsgStream & msg() const
The standard message stream.
bool msgLvl(const MSG::Level lvl) const
Test the output level.

◆ getMaterialInternal() [1/3]

const GeoMaterial * InDetMaterialManager::getMaterialInternal ( const std::string & name,
const std::vector< std::string > & materialComponents,
const std::vector< double > & fractWeights,
double density )
private

Definition at line 666 of file InDetMaterialManager.cxx.

669 {
670 const GeoMaterial* newMaterial = nullptr;
671
672 // First see if we already have the material
673 const GeoMaterial* material = getAdditionalMaterial(name);
674
675 if (material) {
676 if (!compareDensity(material->getDensity(), density)) {
677 ATH_MSG_WARNING("Density is not consistent for material " << name);
678 }
679 newMaterial = material;
680 } else {
681 GeoMaterial* newMaterialTmp = new GeoMaterial(name, density);
682 for (unsigned int i = 0; i < materialComponents.size(); i++) {
683 const GeoMaterial* origMaterial = getMaterialInternal(materialComponents[i]);
684 if (origMaterial) {
685 newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), fracWeight[i]);
686 } else {
687 ATH_MSG_ERROR("Material component missing " << materialComponents[i]);
688 }
689 }
690 addMaterial(newMaterialTmp);
691 newMaterial = newMaterialTmp;
692 }
693 return newMaterial;
694}
bool compareDensity(double d1, double d2) const

◆ getMaterialInternal() [2/3]

const GeoMaterial * InDetMaterialManager::getMaterialInternal ( std::string_view materialName)
private

Definition at line 109 of file InDetMaterialManager.cxx.

109 {
110 // First check local store of materials. If not found then get it from the GeoModel
111 // manager.
112 const GeoMaterial* material = getAdditionalMaterial(materialName);
113
114 if (!material) {
115 if(!m_materialManager) {
116 std::string errorMessage("Null pointer to Stored Material Manager!");
117 ATH_MSG_FATAL(errorMessage);
118 throw std::runtime_error(errorMessage);
119 }
120 // This prints error message if not found.
121 material = m_materialManager->getMaterial(materialName);
122 }
123 return material;
124}

◆ getMaterialInternal() [3/3]

const GeoMaterial * InDetMaterialManager::getMaterialInternal ( std::string_view origMaterialName,
double density,
std::string_view newName = {} )
private

Definition at line 217 of file InDetMaterialManager.cxx.

219 {
220 std::string newName2{newName};
221 bool newNameProvided = !newName2.empty();
222 if (!newNameProvided) {
223 newName2 = std::string{origMaterialName} + "Modified";
224 }
225
226 const GeoMaterial* newMaterial = nullptr;
227
228 // First see if we already have the modified material
229 const GeoMaterial* material = getAdditionalMaterial(newName2);
230 if (material) {
231 if (!compareDensity(material->getDensity(), density)) {
232 ATH_MSG_WARNING("Density is not consistent for material " << newName2
233 << " " << material->getDensity() / (GeoModelKernelUnits::gram / Gaudi::Units::cm3)
234 << " / " << density / (GeoModelKernelUnits::gram / Gaudi::Units::cm3));
235 }
236 newMaterial = material;
237 } else {
238 const GeoMaterial* origMaterial = getMaterialInternal(origMaterialName);
239 newMaterial = origMaterial;
240 if (origMaterial) {
241 // If no new name was provided we check if the density is compatible
242 // and if so we return the original material.
243 if (newNameProvided || !compareDensity(origMaterial->getDensity(), density)) {
244 // create new material
245 GeoMaterial* newMaterialTmp = new GeoMaterial(newName2, density);
246 newMaterialTmp->add(const_cast<GeoMaterial*>(origMaterial), 1.);
247 addMaterial(newMaterialTmp);
248 newMaterial = newMaterialTmp;
249 }
250 }
251 }
252 return newMaterial;
253}

◆ getMaterialScaled()

const GeoMaterial * InDetMaterialManager::getMaterialScaled ( const std::string & origMaterialName,
double scaleFactor,
const std::string & newName = "" )

Definition at line 256 of file InDetMaterialManager.cxx.

258 {
259 return extraScaledMaterial(origMaterialName, newName,
260 getMaterialScaledInternal(origMaterialName, scaleFactor, newName));
261}
const GeoMaterial * getMaterialScaledInternal(const std::string &origMaterialName, double scaleFactor, const std::string &newName="")

◆ getMaterialScaledInternal()

const GeoMaterial * InDetMaterialManager::getMaterialScaledInternal ( const std::string & origMaterialName,
double scaleFactor,
const std::string & newName = "" )
private

Definition at line 264 of file InDetMaterialManager.cxx.

266 {
267 // Don't allow large scale factors
268 if (scaleFactor > 1000 || scaleFactor < 0.001) {
269 ATH_MSG_ERROR("Scale factor must be between 0.001 and 1000.");
270 return nullptr;
271 }
272
273 const GeoMaterial* origMaterial = getMaterialInternal(origMaterialName);
274
275 // If scalefactor is 1 and no new name is requested
276 // then just return the orginal material
277 if (newName.empty() && scaleFactor == 1.) return origMaterial;
278
279 const GeoMaterial* newMaterial = nullptr;
280
281 if (origMaterial) {
282 double density = origMaterial->getDensity() * scaleFactor;
283 std::string newName2 = newName;
284 if (newName2.empty()) {
285 // Create name using the scale factor.
286 int scaleInt = static_cast<int>(scaleFactor * 10000);
287 int scale1 = scaleInt / 10000;
288 int scale2 = scaleInt % 10000;
289
290 std::ostringstream os;
291 os << origMaterialName << scale1 << "_" << std::setw(4) << std::setfill('0') << scale2;
292 newName2 = os.str();
293 }
294
295 newMaterial = getMaterialInternal(origMaterialName, density, newName2);
296 }
297
298 return newMaterial;
299}
#define scale2
#define scale1

◆ hasMaterial()

bool InDetMaterialManager::hasMaterial ( const std::string & materialName) const

Definition at line 104 of file InDetMaterialManager.cxx.

104 {
105 return m_weightMap.find(materialName) != m_weightMap.end();
106}

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 167 of file AthMessaging.h.

168{
169 MsgStream* ms = m_msg_tls.get();
170 if (!ms) {
171 if (!m_initialized.test_and_set()) initMessaging();
172 ms = new MsgStream(m_imsg,m_nm);
173 m_msg_tls.reset( ms );
174 }
175
176 ms->setLevel (m_lvl);
177 return *ms;
178}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels).
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 182 of file AthMessaging.h.

183{ return msg() << lvl; }

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 // If user did not set explicit message level we have to initialize
154 // the messaging and retrieve the default via the MessageSvc.
155 if (m_lvl==MSG::NIL && !m_initialized.test_and_set()) initMessaging();
156
157 if (m_lvl <= lvl) {
158 msg() << lvl;
159 return true;
160 } else {
161 return false;
162 }
163}

◆ retrieveManager()

StoredMaterialManager * InDetMaterialManager::retrieveManager ( const StoreGateSvc * detStore)
inlineprivate

Definition at line 84 of file InDetMaterialManager.cxx.

84 {
85 return detStore->tryRetrieve<StoredMaterialManager>("MATERIALS");
86}
T * tryRetrieve() const
Variant of the above which doesn't print a warning message.

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging).

Definition at line 141 of file AthMessaging.h.

◆ m_extraFunctionality

bool InDetMaterialManager::m_extraFunctionality
private

Definition at line 225 of file InDetMaterialManager.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_managerName

std::string InDetMaterialManager::m_managerName
private

Definition at line 210 of file InDetMaterialManager.h.

◆ m_matCompositionMap

MaterialCompositionMap InDetMaterialManager::m_matCompositionMap
private

Definition at line 219 of file InDetMaterialManager.h.

◆ m_materialManager

StoredMaterialManager* InDetMaterialManager::m_materialManager
private

Definition at line 209 of file InDetMaterialManager.h.

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels).

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_scalingMap

ExtraScaleFactorMap InDetMaterialManager::m_scalingMap
private

Definition at line 222 of file InDetMaterialManager.h.

◆ m_store

MaterialStore InDetMaterialManager::m_store
private

Definition at line 213 of file InDetMaterialManager.h.

◆ m_weightMap

MaterialWeightMap InDetMaterialManager::m_weightMap
private

Definition at line 216 of file InDetMaterialManager.h.


The documentation for this class was generated from the following files: